|
|
1.1 ! root 1: #title s p i t b o l - revision history ! 2: #page ! 3: # R E V I S I O N H I S T O R Y ! 4: # ------------------------------- ! 5: # ! 6: # ! 7: # VERSION 3.5B (FEB 81... - SGD PATCHES) ! 8: # ----------------------------------- ! 9: # ! 10: # SGD03 - ADDITION OF .CNCI AND SYSCI (INT->STRING ! 11: # SYSTEM ROUTINE OPTION) ! 12: # SGD04 - (06-MAY-1981) MODIFIED INILN TO 132 ! 13: # SGD05 - (13-MAY-1981) INSERTED MISSING WTB AFTER SYSMM ! 14: # CALLS ! 15: # SGD06 - (25-MAY-1981) MERGED IN PROFILER PATCHES ! 16: # (NOT MARKED) ! 17: # SGD07 - (25-MAY-1981) MUCHO PATCHES TO PROFILER (MARKED, ! 18: # BUT BEST JUST TO EXTRACT ENMASSE) ! 19: # SGD08 - (25-MAY-1981) USE STRING LENGTH IN HASHS ! 20: # SGD09 - (25-MAY-1981) FIXED SERIOUS PARSER PROBLEM ! 21: # RELATING TO (X Y) ON LINE BEING VIEWED AS PATTERN ! 22: # MATCH. FIXED BY ADDITION OF NEW CMTYP VALUE ! 23: # C$CNP (CONCATENATION - NOT PATTERN MATCH) ! 24: # SGD10 - (01-AUG-1981) FIXED EXIT(N) RESPECIFICATION CODE ! 25: # TO PROPERLY OBSERVE HEADER SEMANTICS ON RETURN. ! 26: # SGD11 - (07-AUG-1981) BYPASS PRTPG CALL AT INITIALIZATION ! 27: # FOLLOWING COMPILATION IF NO OUTPUT GENERATED. ! 28: # THIS PREVENTS OUTPUT FILES CONSISTING OF THE ! 29: # HEADERS AND A FEW BLANK LINES WHEN THERE IS NO ! 30: # SOURCE LISTING AND NO COMPILATION STATS. ! 31: # ALSO FIX TIMSX INITIALIZATION IN SAME CODE. ! 32: # SGD12 - (17-AUG-1981) B$EFC CODE DID NOT CHECK FOR ! 33: # UNCONVERTED RESULT RETURNING NULL STRING. FIXED. ! 34: # SGDBF - ( NOV-1981) ADDED BUFFER TYPE AND SYMBOL CNBF ! 35: # SGD13 - (03-MAR-1982) LOAD PFVBL FIELD IN RETRN FOR ! 36: # RETURN TRACING. THIS WAS CAUSING BUG ON RETURN ! 37: # TRACES THAT TRIED TO ACCESS THE VARIABLE NAME ! 38: # SGD14 - ADDED CHAR FUNCTION. CHAR(N) RETURNS NTH ! 39: # CHARACTER OF HOST MACHINE CHARACTER SET. ! 40: # NOT CONDITIONALIZED OR MARKED. ! 41: # SGD15 - FIXED PROBLEM RELATING TO COMPILATION OF GOTO ! 42: # FIELDS CONTAINING SMALL INTEGERS (IN CONST SEC). ! 43: # ! 44: # REG01 - (XX-AUG-82) ! 45: # ADDED CFP$U TO EASE TRANSLATION ON SMALLER ! 46: # SYSTEMS - CONDITIONAL .CUCF ! 47: # ADDED LOWER CASE SUPPORT - CONDITIONAL .CULC ! 48: # ADDED SET I/O FUNCTION - CONDITIONAL .CUST ! 49: # ! 50: # REG02 - (XX-SEP-82) ! 51: # CHANGED INILN AND AND INILS TO 258 ! 52: # ! 53: # REG03 - (XX-OCT-82) ! 54: # CONDITIONALIZED THE PAGE EJECT AFTER CALL TO SYSBX ! 55: # AND ADDED ANOTHER BEFORE CALL TO SYSBX, SO THAT, ! 56: # IF DESIRED BY THE IMPLEMENTOR, STANDARD OUTPUT ! 57: # WILL REFLECT ASSIGNMENTS MADE BY EXECUTING PROGRAM ! 58: # ONLY. CONDITIONAL .CUEJ CONTROLS - IF DEFINED ! 59: # EJECT IS BEFORE CALL TO SYSBX. ! 60: # ! 61: # REG04 - (XX-NOV-82) ! 62: # FIXED DIFFICULTIES WITH LISTINGS DURING EXECUTION ! 63: # WHEN NO LISTING GENERATED DURING COMPILATION. ! 64: # ! 65: # -LIST TO CODE() CAUSED BOMB. FIX IS TO RESET ! 66: # R$TTL AND R$STL TO NULLS NOT 0 AFTER COMPILATION. ! 67: # (LISTR AND LISTT EXPECT NULLS) ! 68: # ! 69: # WHEN LISTING AND STATISTICS ROUTED TO DIFFERENT ! 70: # FILE THAN EXECUTION OUTPUT, ERROR MESSAGE IS SENT ! 71: # TO EXECUTION OUTPUT (AND GETS SEPARATED FROM ! 72: # ... IN STATEMENT ... MSG). LABO1 CALLS SYSAX AND ! 73: # STOPR DOES NOT CALL SYSAX IF ENTERED FROM LABO1. ! 74: # ! 75: # REG05 - (XX-NOV-82) ! 76: # PREVENT CLEAR() FROM CLOBBERING PROTECTED VARIABLES ! 77: # AT LABEL SCLR5. ! 78: # ! 79: # REG06 - (XX-NOV-82) ! 80: # FIXED GTEXP FROM ACCEPTING TRAILING SEMICOLON OR ! 81: # COLON. NOT LEGAL WAY TO END AN EXPRESSION. ! 82: # ! 83: # VERSION 3.5A (OCT 79 - SGD PATCHES) ! 84: # ----------------------------------- ! 85: # ! 86: # SGD01 - PATCH IN ASIGN TO FIX MULTIPLE TRAP BLOCK PROBLEM ! 87: # (ASG10+2) ! 88: # SGD02 - PATCH IN GTARR TO FIX NULL CONVERT (GTAR9+0) ! 89: # ! 90: #title s p i t b o l -- basic information ! 91: #page ! 92: # ! 93: # GENERAL STRUCTURE ! 94: # ----------------- ! 95: # ! 96: # THIS PROGRAM IS A TRANSLATOR FOR A VERSION OF THE SNOBOL4 ! 97: # PROGRAMMING LANGUAGE. LANGUAGE DETAILS ARE CONTAINED IN ! 98: # THE MANUAL MACRO SPITBOL BY DEWAR AND MCCANN, TECHNICAL ! 99: # REPORT 90, UNIVERSITY OF LEEDS 1976. THE LANGUAGE ! 100: # IS IDENTICAL TO THAT IMPLEMENTED BY THE BTL TRANSLATOR ! 101: # (R. E. GRISWOLD ET AL.) WITH THE FOLLOWING EXCEPTIONS. ! 102: # ! 103: # 1) REDEFINITION OF STANDARD SYSTEM FUNCTIONS AND ! 104: # OPERATORS IS NOT PERMITTED. ! 105: # ! 106: # 2) THE VALUE FUNCTION IS NOT PROVIDED. ! 107: # ! 108: # 3) ACCESS TRACING IS PROVIDED IN ADDITION TO THE ! 109: # OTHER STANDARD TRACE MODES. ! 110: # ! 111: # 4) THE KEYWORD STFCOUNT IS NOT PROVIDED. ! 112: # ! 113: # 5) THE KEYWORD FULLSCAN IS NOT PROVIDED AND ALL PATTERN ! 114: # MATCHING TAKES PLACE IN FULLSCAN MODE (I.E. WITH NO ! 115: # HEURISTICS APPLIED). ! 116: # ! 117: # 6) A SERIES OF EXPRESSIONS SEPARATED BY COMMAS MAY ! 118: # BE GROUPED WITHIN PARENTHESES TO PROVIDE A SELECTION ! 119: # CAPABILITY. THE SEMANTICS ARE THAT THE SELECTION ! 120: # ASSUMES THE VALUE OF THE FIRST EXPRESSION WITHIN IT ! 121: # WHICH SUCCEEDS AS THEY ARE EVALUATED FROM THE LEFT. ! 122: # IF NO EXPRESSION SUCCEEDS THE ENTIRE STATEMENT FAILS ! 123: # ! 124: # 7) AN EXPLICIT PATTERN MATCHING OPERATOR IS PROVIDED. ! 125: # THIS IS THE BINARY QUERY (SEE GIMPEL SIGPLAN OCT 74) ! 126: # ! 127: # 8) THE ASSIGNMENT OPERATOR IS INTRODUCED AS IN THE ! 128: # GIMPEL REFERENCE. ! 129: # ! 130: # 9) THE EXIT FUNCTION IS PROVIDED FOR GENERATING LOAD ! 131: # MODULES - CF. GIMPELS SITBOL. ! 132: # ! 133: # ! 134: # THE METHOD USED IN THIS PROGRAM IS TO TRANSLATE THE ! 135: # SOURCE CODE INTO AN INTERNAL PSEUDO-CODE (SEE FOLLOWING ! 136: # SECTION). AN INTERPRETOR IS THEN USED TO EXECUTE THIS ! 137: # GENERATED PSEUDO-CODE. THE NATURE OF THE SNOBOL4 LANGUAGE ! 138: # IS SUCH THAT THE LATTER TASK IS MUCH MORE COMPLEX THAN ! 139: # THE ACTUAL TRANSLATION PHASE. ACCORDINGLY, NEARLY ALL THE ! 140: # CODE IN THE PROGRAM SECTION IS CONCERNED WITH THE ACTUAL ! 141: # EXECUTION OF THE SNOBOL4 PROGRAM. ! 142: #page ! 143: # ! 144: # INTERPRETIVE CODE FORMAT ! 145: # ------------------------ ! 146: # ! 147: # THE INTERPRETIVE PSEUDO-CODE CONSISTS OF A SERIES OF ! 148: # ADDRESS POINTERS. THE EXACT FORMAT OF THE CODE IS ! 149: # DESCRIBED IN CONNECTION WITH THE CDBLK FORMAT. THE ! 150: # PURPOSE OF THIS SECTION IS TO GIVE GENERAL INSIGHT INTO ! 151: # THE INTERPRETIVE APPROACH INVOLVED. ! 152: # ! 153: # THE BASIC FORM OF THE CODE IS RELATED TO REVERSE POLISH. ! 154: # IN OTHER WORDS, THE OPERANDS PRECEDE THE OPERATORS WHICH ! 155: # ARE ZERO ADDRESS OPERATORS. THERE ARE SOME EXCEPTIONS TO ! 156: # THESE RULES, NOTABLY THE UNARY NOT OPERATOR AND THE ! 157: # SELECTION CONSTRUCTION WHICH CLEARLY REQUIRE ADVANCE ! 158: # KNOWLEDGE OF THE OPERATOR INVOLVED. ! 159: # ! 160: # THE OPERANDS ARE MOVED TO THE TOP OF THE MAIN STACK AND ! 161: # THE OPERATORS ARE APPLIED TO THE TOP STACK ENTRIES. LIKE ! 162: # OTHER VERSIONS OF SPITBOL, THIS PROCESSOR DEPENDS ON ! 163: # KNOWING WHETHER OPERANDS ARE REQUIRED BY NAME OR BY VALUE ! 164: # AND MOVES THE APPROPRIATE OBJECT TO THE STACK. THUS NO ! 165: # NAME/VALUE CHECKS ARE INCLUDED IN THE OPERATOR CIRCUITS. ! 166: # ! 167: # THE ACTUAL POINTERS IN THE CODE POINT TO A BLOCK WHOSE ! 168: # FIRST WORD IS THE ADDRESS OF THE INTERPRETOR ROUTINE ! 169: # TO BE EXECUTED FOR THE CODE WORD. ! 170: # ! 171: # IN THE CASE OF OPERATORS, THE POINTER IS TO A WORD WHICH ! 172: # CONTAINS THE ADDRESS OF THE OPERATOR TO BE EXECUTED. IN ! 173: # THE CASE OF OPERANDS SUCH AS CONSTANTS, THE POINTER IS TO ! 174: # THE OPERAND ITSELF. ACCORDINGLY, ALL OPERANDS CONTAIN ! 175: # A FIELD WHICH POINTS TO THE ROUTINE TO LOAD THE VALUE OF ! 176: # THE OPERAND ONTO THE STACK. IN THE CASE OF A VARIABLE, ! 177: # THERE ARE THREE SUCH POINTERS. ONE TO LOAD THE VALUE, ! 178: # ONE TO STORE THE VALUE AND A THIRD TO JUMP TO THE LABEL. ! 179: # ! 180: # THE HANDLING OF FAILURE RETURNS DESERVES SPECIAL COMMENT. ! 181: # THE LOCATION FLPTR CONTAINS THE POINTER TO THE LOCATION ! 182: # ON THE MAIN STACK WHICH CONTAINS THE FAILURE RETURN ! 183: # WHICH IS IN THE FORM OF A BYTE OFFSET IN THE CURRENT ! 184: # CODE BLOCK (CDBLK OR EXBLK). WHEN A FAILURE OCCURS, THE ! 185: # STACK IS POPPED AS INDICATED BY THE SETTING OF FLPTR AND ! 186: # CONTROL IS PASSED TO THE APPROPRIATE LOCATION IN THE ! 187: # CURRENT CODE BLOCK WITH THE STACK POINTER POINTING TO THE ! 188: # FAILURE OFFSET ON THE STACK AND FLPTR UNCHANGED. ! 189: #page ! 190: # ! 191: # INTERNAL DATA REPRESENTATIONS ! 192: # ----------------------------- ! 193: # ! 194: # REPRESENTATION OF VALUES ! 195: # ! 196: # A VALUE IS REPRESENTED BY A POINTER TO A BLOCK WHICH ! 197: # DESCRIBES THE TYPE AND PARTICULARS OF THE DATA VALUE. ! 198: # IN GENERAL, A VARIABLE IS A LOCATION CONTAINING SUCH A ! 199: # POINTER (ALTHOUGH IN THE CASE OF TRACE ASSOCIATIONS THIS ! 200: # IS MODIFIED, SEE DESCRIPTION OF TRBLK). ! 201: # ! 202: # THE FOLLOWING IS A LIST OF POSSIBLE DATATYPES SHOWING THE ! 203: # TYPE OF BLOCK USED TO HOLD THE VALUE. THE DETAILS OF ! 204: # EACH BLOCK FORMAT ARE GIVEN LATER. ! 205: # ! 206: # DATATYPE BLOCK TYPE ! 207: # -------- ---------- ! 208: # ! 209: # ! 210: # ARRAY ARBLK OR VCBLK ! 211: # ! 212: # CODE CDBLK ! 213: # ! 214: # EXPRESSION EXBLK OR SEBLK ! 215: # ! 216: # INTEGER ICBLK ! 217: # ! 218: # NAME NMBLK ! 219: # ! 220: # PATTERN P0BLK OR P1BLK OR P2BLK ! 221: # ! 222: # REAL RCBLK ! 223: # ! 224: # STRING SCBLK ! 225: # ! 226: # TABLE TBBLK ! 227: # ! 228: # PROGRAM DATATYPE PDBLK ! 229: #page ! 230: # ! 231: # REPRESENTATION OF VARIABLES ! 232: # --------------------------- ! 233: # ! 234: # DURING THE COURSE OF EVALUATING EXPRESSIONS, IT IS ! 235: # NECESSARY TO GENERATE NAMES OF VARIABLES (FOR EXAMPLE ! 236: # ON THE LEFT SIDE OF A BINARY EQUALS OPERATOR). THESE ARE ! 237: # NOT TO BE CONFUSED WITH OBJECTS OF DATATYPE NAME WHICH ! 238: # ARE IN FACT VALUES. ! 239: # ! 240: # FROM A LOGICAL POINT OF VIEW, SUCH NAMES COULD BE SIMPLY ! 241: # REPRESENTED BY A POINTER TO THE APPROPRIATE VALUE CELL. ! 242: # HOWEVER IN THE CASE OF ARRAYS AND PROGRAM DEFINED ! 243: # DATATYPES, THIS WOULD VIOLATE THE RULE THAT THERE MUST BE ! 244: # NO POINTERS INTO THE MIDDLE OF A BLOCK IN DYNAMIC STORE. ! 245: # ACCORDINGLY, A NAME IS ALWAYS REPRESENTED BY A BASE AND ! 246: # OFFSET. THE BASE POINTS TO THE START OF THE BLOCK ! 247: # CONTAINING THE VARIABLE VALUE AND THE OFFSET IS THE ! 248: # OFFSET WITHIN THIS BLOCK IN BYTES. THUS THE ADDRESS ! 249: # OF THE ACTUAL VARIABLE IS DETERMINED BY ADDING THE BASE ! 250: # AND OFFSET VALUES. ! 251: # ! 252: # THE FOLLOWING ARE THE INSTANCES OF VARIABLES REPRESENTED ! 253: # IN THIS MANNER. ! 254: # ! 255: # 1) NATURAL VARIABLE BASE IS PTR TO VRBLK ! 256: # OFFSET IS *VRVAL ! 257: # ! 258: # 2) TABLE ELEMENT BASE IS PTR TO TEBLK ! 259: # OFFSET IS *TEVAL ! 260: # ! 261: # 3) ARRAY ELEMENT BASE IS PTR TO ARBLK ! 262: # OFFSET IS OFFSET TO ELEMENT ! 263: # ! 264: # 4) VECTOR ELEMENT BASE IS PTR TO VCBLK ! 265: # OFFSET IS OFFSET TO ELEMENT ! 266: # ! 267: # 5) PROG DEF DTP BASE IS PTR TO PDBLK ! 268: # OFFSET IS OFFSET TO FIELD VALUE ! 269: # ! 270: # IN ADDITION THERE ARE TWO CASES OF OBJECTS WHICH ARE ! 271: # LIKE VARIABLES BUT CANNOT BE HANDLED IN THIS MANNER. ! 272: # THESE ARE CALLED PSEUDO-VARIABLES AND ARE REPRESENTED ! 273: # WITH A SPECIAL BASE POINTER AS FOLLOWS= ! 274: # ! 275: # EXPRESSION VARIABLE PTR TO EVBLK (SEE EVBLK) ! 276: # ! 277: # KEYWORD VARIABLE PTR TO KVBLK (SEE KVBLK) ! 278: # ! 279: # PSEUDO-VARIABLES ARE HANDLED AS SPECIAL CASES BY THE ! 280: # ACCESS PROCEDURE (ACESS) AND THE ASSIGNMENT PROCEDURE ! 281: # (ASIGN). SEE THESE TWO PROCEDURES FOR DETAILS. ! 282: #page ! 283: # ! 284: # ORGANIZATION OF DATA AREA ! 285: # ------------------------- ! 286: # ! 287: # ! 288: # THE DATA AREA IS DIVIDED INTO TWO REGIONS. ! 289: # ! 290: # STATIC AREA ! 291: # ! 292: # THE STATIC AREA BUILDS UP FROM THE BOTTOM AND CONTAINS ! 293: # DATA AREAS WHICH ARE ALLOCATED DYNAMICALLY BUT ARE NEVER ! 294: # DELETED OR MOVED AROUND. THE MACRO-PROGRAM ITSELF ! 295: # USES THE STATIC AREA FOR THE FOLLOWING. ! 296: # ! 297: # 1) ALL VARIABLE BLOCKS (VRBLK). ! 298: # ! 299: # 2) THE HASH TABLE FOR VARIABLE BLOCKS. ! 300: # ! 301: # 3) MISCELLANEOUS BUFFERS AND WORK AREAS (SEE PROGRAM ! 302: # INITIALIZATION SECTION). ! 303: # ! 304: # IN ADDITION, THE SYSTEM PROCEDURES MAY USE THIS AREA FOR ! 305: # INPUT/OUTPUT BUFFERS, EXTERNAL FUNCTIONS ETC. SPACE IN ! 306: # THE STATIC REGION IS ALLOCATED BY CALLING PROCEDURE ALOST ! 307: # ! 308: # THE FOLLOWING GLOBAL VARIABLES DEFINE THE CURRENT ! 309: # LOCATION AND SIZE OF THE STATIC AREA. ! 310: # ! 311: # STATB ADDRESS OF START OF STATIC AREA ! 312: # STATE ADDRESS+1 OF LAST WORD IN AREA. ! 313: # ! 314: # THE MINIMUM SIZE OF STATIC IS GIVEN APPROXIMATELY BY ! 315: # 12 + *E$HNB + *E$STS + SPACE FOR ALPHABET STRING ! 316: # AND STANDARD PRINT BUFFER. ! 317: #page ! 318: # ! 319: # DYNAMIC AREA ! 320: # ! 321: # THE DYNAMIC AREA IS BUILT UPWARDS IN MEMORY AFTER THE ! 322: # STATIC REGION. DATA IN THIS AREA MUST ALL BE IN STANDARD ! 323: # BLOCK FORMATS SO THAT IT CAN BE PROCESSED BY THE GARBAGE ! 324: # COLLECTOR (PROCEDURE GBCOL). GBCOL COMPACTS BLOCKS DOWN ! 325: # IN THIS REGION AS REQUIRED BY SPACE EXHAUSTION AND CAN ! 326: # ALSO MOVE ALL BLOCKS UP TO ALLOW FOR EXPANSION OF THE ! 327: # STATIC REGION. ! 328: # WITH THE EXCEPTION OF TABLES AND ARRAYS, NO SPITBOL ! 329: # OBJECT ONCE BUILT IN DYNAMIC MEMORY IS EVER SUBSEQUENTLY ! 330: # MODIFIED. OBSERVING THIS RULE NECESSITATES A COPYING ! 331: # ACTION DURING STRING AND PATTERN CONCATENATION. ! 332: # ! 333: # GARBAGE COLLECTION IS FUNDAMENTAL TO THE ALLOCATION OF ! 334: # SPACE FOR VALUES. SPITBOL USES A VERY EFFICIENT GARBAGE ! 335: # COLLECTOR WHICH INSISTS THAT POINTERS INTO DYNAMIC STORE ! 336: # SHOULD BE IDENTIFIABLE WITHOUT USE OF BIT TABLES, ! 337: # MARKER BITS ETC. TO SATISFY THIS REQUIREMENT, DYNAMIC ! 338: # MEMORY MUST NOT START AT TOO LOW AN ADDRESS AND LENGTHS ! 339: # OF ARRAYS, TABLES, STRINGS, CODE AND EXPRESSION BLOCKS ! 340: # MAY NOT EXCEED THE NUMERICAL VALUE OF THE LOWEST DYNAMIC ! 341: # ADDRESS. TO AVOID EITHER PENALIZING USERS WITH MODEST ! 342: # REQUIREMENTS OR RESTRICTING THOSE WITH GREATER NEEDS ON ! 343: # HOST SYSTEMS WHERE DYNAMIC MEMORY IS ALLOCATED IN LOW ! 344: # ADDRESSES, THE MINIMUM DYNAMIC ADDRESS MAY BE SPECIFIED ! 345: # SUFFICIENTLY HIGH TO PERMIT ARBITRARILY LARGE SPITBOL ! 346: # OBJECTS TO BE CREATED ( WITH THE POSSIBILITY IN EXTREME ! 347: # CASES OF WASTING LARGE AMOUNTS OF MEMORY BELOW THE ! 348: # START ADDRESS). THIS MINIMUM VALUE IS MADE AVAILABLE ! 349: # IN VARIABLE MXLEN BY A SYSTEM ROUTINE, SYSMX. ! 350: # ALTERNATIVELY SYSMX MAY INDICATE THAT A ! 351: # DEFAULT MAY BE USED IN WHICH DYNAMIC IS PLACED ! 352: # AT THE LOWEST POSSIBLE ADDRESS FOLLOWING STATIC. ! 353: # ! 354: # THE FOLLOWING GLOBAL WORK CELLS DEFINE THE LOCATION AND ! 355: # LENGTH OF THE DYNAMIC AREA. ! 356: # ! 357: # DNAMB START OF DYNAMIC AREA ! 358: # DNAMP NEXT AVAILABLE LOCATION ! 359: # DNAME LAST AVAILABLE LOCATION + 1 ! 360: # ! 361: # DNAMB IS ALWAYS HIGHER THAN STATE SINCE THE ALOST ! 362: # PROCEDURE MAINTAINS SOME EXPANSION SPACE ABOVE STATE. ! 363: # *** DNAMB MUST NEVER BE PERMITTED TO HAVE A VALUE LESS ! 364: # THAN THAT IN MXLEN *** ! 365: # ! 366: # SPACE IN THE DYNAMIC REGION IS ALLOCATED BY THE ALLOC ! 367: # PROCEDURE. THE DYNAMIC REGION MAY BE USED BY SYSTEM ! 368: # PROCEDURES PROVIDED THAT ALL THE RULES ARE OBEYED. ! 369: #page ! 370: # ! 371: # REGISTER USAGE ! 372: # -------------- ! 373: # ! 374: # (CP) CODE POINTER REGISTER. USED TO ! 375: # HOLD A POINTER TO THE CURRENT ! 376: # LOCATION IN THE INTERPRETIVE PSEUDO ! 377: # CODE (I.E. PTR INTO A CDBLK). ! 378: # ! 379: # (XL,XR) GENERAL INDEX REGISTERS. USUALLY ! 380: # USED TO HOLD POINTERS TO BLOCKS IN ! 381: # DYNAMIC STORAGE. AN IMPORTANT ! 382: # RESTRICTION IS THAT THE VALUE IN ! 383: # XL MUST BE COLLECTABLE FOR ! 384: # A GARBAGE COLLECT CALL. A VALUE ! 385: # IS COLLECTABLE IF IT EITHER POINTS ! 386: # OUTSIDE THE DYNAMIC AREA, OR IF IT ! 387: # POINTS TO THE START OF A BLOCK IN ! 388: # THE DYNAMIC AREA. ! 389: # ! 390: # (XS) STACK POINTER. USED TO POINT TO ! 391: # THE STACK FRONT. THE STACK MAY ! 392: # BUILD UP OR DOWN AND IS USED ! 393: # TO STACK SUBROUTINE RETURN POINTS ! 394: # AND OTHER RECURSIVELY SAVED DATA. ! 395: # ! 396: # (XT) AN ALTERNATIVE NAME FOR XL DURING ! 397: # ITS USE IN ACCESSING STACKED ITEMS. ! 398: # ! 399: # (WA,WB,WC) GENERAL WORK REGISTERS. CANNOT BE ! 400: # USED FOR INDEXING, BUT MAY HOLD ! 401: # VARIOUS TYPES OF DATA. ! 402: # ! 403: # (IA) USED FOR ALL SIGNED INTEGER ! 404: # ARITHMETIC, BOTH THAT USED BY THE ! 405: # TRANSLATOR AND THAT ARISING FROM ! 406: # USE OF SNOBOL4 ARITHMETIC OPERATORS ! 407: # ! 408: # (RA) REAL ACCUMULATOR. USED FOR ALL ! 409: # FLOATING POINT ARITHMETIC. ! 410: #page ! 411: # ! 412: # SPITBOL CONDITIONAL ASSEMBLY SYMBOLS ! 413: # ------------------------------------ ! 414: # ! 415: # IN THE SPITBOL TRANSLATOR, THE FOLLOWING CONDITIONAL ! 416: # ASSEMBLY SYMBOLS ARE REFERRED TO. TO INCORPORATE THE ! 417: # FEATURES REFERRED TO, THE MINIMAL SOURCE SHOULD BE ! 418: # PREFACED BY SUITABLE CONDITIONAL ASSEMBLY SYMBOL ! 419: # DEFINITIONS. ! 420: # IN ALL CASES IT IS PERMISSIBLE TO DEFAULT THE DEFINITIONS ! 421: # IN WHICH CASE THE ADDITIONAL FEATURES WILL BE OMITTED ! 422: # FROM THE TARGET CODE. ! 423: # ! 424: # .CASL DEFINE TO INCLUDE 26 SHIFTED LETTRS ! 425: # .CAHT DEFINE TO INCLUDE HORIZONTAL TAB ! 426: # .CAVT DEFINE TO INCLUDE VERTICAL TAB ! 427: # .CIOD IF DEFINED, DEFAULT DELIMITER IS ! 428: # NOT USED IN PROCESSING 3RD ARG OF ! 429: # INPUT() AND OUTPUT() ! 430: # .CNBT DEFINE TO OMIT BATCH INITIALISATION ! 431: # .CNCI DEFINE TO ENABLE SYSCI ROUTINE ! 432: # .CNEX DEFINE TO OMIT EXIT() CODE. ! 433: # .CNLD DEFINE TO OMIT LOAD() CODE. ! 434: # .CNPF DEFINE TO OMIT PROFILE STUFF ! 435: # .CNRA DEFINE TO OMIT ALL REAL ARITHMETIC ! 436: # .CNSR DEFINE TO OMIT SORT, RSORT ! 437: # .CSAX DEFINE IF SYSAX IS TO BE CALLED ! 438: # .CSN6 DEFINE TO PAD STMT NOS TO 6 CHARS ! 439: # .CSN8 DEFINE TO PAD STMT NOS TO 8 CHARS ! 440: # .CUCF DEFINE TO INCLUDE CFP$U ! 441: # .CULC DEFINE TO INCLUDE &CASE (LC NAMES) ! 442: # .CUST DEFINE TO INCLUDE SET() CODE ! 443: #title s p i t b o l -- procedures section ! 444: # ! 445: # THIS SECTION STARTS WITH DESCRIPTIONS OF THE OPERATING ! 446: # SYSTEM DEPENDENT PROCEDURES WHICH ARE USED BY THE SPITBOL ! 447: # TRANSLATOR. ALL SUCH PROCEDURES HAVE FIVE LETTER NAMES ! 448: # BEGINNING WITH SYS. THEY ARE LISTED IN ALPHABETICAL ! 449: # ORDER. ! 450: # ALL PROCEDURES HAVE A SPECIFICATION CONSISTING OF A ! 451: # MODEL CALL, PRECEDED BY A POSSIBLY EMPTY LIST OF REGISTER ! 452: # CONTENTS GIVING PARAMETERS AVAILABLE TO THE PROCEDURE AND ! 453: # FOLLOWED BY A POSSIBLY EMPTY LIST OF REGISTER CONTENTS ! 454: # REQUIRED ON RETURN FROM THE CALL OR WHICH MAY HAVE HAD ! 455: # THEIR CONTENTS DESTROYED. ONLY THOSE REGISTERS EXPLICITLY ! 456: # MENTIONED IN THE LIST AFTER THE CALL MAY HAVE THEIR ! 457: # VALUES CHANGED. ! 458: # THE SEGMENT OF CODE PROVIDING THE EXTERNAL PROCEDURES IS ! 459: # CONVENIENTLY REFERRED TO AS OSINT (OPERATING SYSTEM ! 460: # INTERFACE). THE SYSXX PROCEDURES IT CONTAINS PROVIDE ! 461: # FACILITIES NOT USUALLY AVAILABLE AS PRIMITIVES IN ! 462: # ASSEMBLY LANGUAGES. FOR PARTICULAR TARGET MACHINES, ! 463: # IMPLEMENTORS MAY CHOOSE FOR SOME MINIMAL OPCODES WHICH ! 464: # DO NOT HAVE REASONABLY DIRECT TRANSLATIONS, TO USE CALLS ! 465: # OF ADDITIONAL PROCEDURES WHICH THEY PROVIDE IN OSINT. ! 466: # E.G. MWB OR TRC MIGHT BE TRANSLATED AS JSR SYSMB, ! 467: # JSR SYSTC IN SOME IMPLEMENTATIONS. ! 468: # ! 469: # IN THE DESCRIPTIONS, REFERENCE IS MADE TO --BLK ! 470: # FORMATS (-- = A PAIR OF LETTERS). SEE THE SPITBOL ! 471: # DEFINITIONS SECTION FOR DETAILED DESCRIPTIONS OF ALL ! 472: # SUCH BLOCK FORMATS EXCEPT FCBLK FOR WHICH SYSFC SHOULD ! 473: # BE CONSULTED. ! 474: # ! 475: # SECTION 0 CONTAINS INP,INR SPECIFICATIONS OF INTERNAL ! 476: # PROCEDURES,ROUTINES. THIS GIVES A SINGLE PASS TRANSLATOR ! 477: # INFORMATION MAKING IT EASY TO GENERATE ALTERNATIVE CALLS ! 478: # IN THE TRANSLATION OF JSR-S FOR PROCEDURES OF DIFFERENT ! 479: # TYPES IF THIS PROVES NECESSARY. ! 480: # ! 481: #sec # start of procedures section ! 482: #page ! 483: # ! 484: # SYSAX -- AFTER EXECUTION ! 485: # ! 486: .globl sysax # define external entry point ! 487: # ! 488: # IF THE CONDITIONAL ASSEMBLY SYMBOL .CSAX IS DEFINED, ! 489: # THIS ROUTINE IS CALLED IMMEDIATELY AFTER EXECUTION AND ! 490: # BEFORE PRINTING OF EXECUTION STATISTICS OR DUMP OUTPUT. ! 491: # PURPOSE OF CALL IS FOR IMPLEMENTOR TO DETERMINE AND ! 492: # IF THE CALL IS NOT REQUIRED IT WILL BE OMITTED IF .CSAX ! 493: # IS UNDEFINED. IN THIS CASE SYSAX NEED NOT BE CODED. ! 494: # ! 495: # JSR SYSAX CALL AFTER EXECUTION ! 496: #page ! 497: # ! 498: # SYSBX -- BEFORE EXECUTION ! 499: # ! 500: .globl sysbx # define external entry point ! 501: # ! 502: # CALLED AFTER INITIAL SPITBOL COMPILATION AND BEFORE ! 503: # COMMENCING EXECUTION IN CASE OSINT NEEDS ! 504: # TO ASSIGN FILES OR PERFORM OTHER NECESSARY SERVICES. ! 505: # OSINT MAY ALSO CHOOSE TO SEND A MESSAGE TO ONLINE ! 506: # TERMINAL (IF ANY) INDICATING THAT EXECUTION IS STARTING. ! 507: # ! 508: # JSR SYSBX CALL BEFORE EXECUTION STARTS ! 509: #page ! 510: # ! 511: # SYSDC -- DATE CHECK ! 512: # ! 513: .globl sysdc # define external entry point ! 514: # ! 515: # SYSDC IS CALLED TO CHECK THAT THE EXPIRY DATE FOR A TRIAL ! 516: # VERSION OF SPITBOL IS UNEXPIRED. ! 517: # ! 518: # JSR SYSDC CALL TO CHECK DATE ! 519: # RETURN ONLY IF DATE IS OK ! 520: #page ! 521: # ! 522: # SYSDM -- DUMP CORE ! 523: # ! 524: .globl sysdm # define external entry point ! 525: # ! 526: # SYSDM IS CALLED BY A SPITBOL PROGRAM CALL OF DUMP(N) WITH ! 527: # N GE 3. ITS PURPOSE IS TO PROVIDE A CORE DUMP. ! 528: # N COULD HOLD AN ENCODING OF THE START ADRS FOR DUMP AND ! 529: # AMOUNT TO BE DUMPED E.G. N = 256*A + S , S = START ADRS ! 530: # IN KILOWORDS, A = KILOWORDS TO DUMP ! 531: # ! 532: # (XR) PARAMETER N OF CALL DUMP(N) ! 533: # JSR SYSDM CALL TO ENTER ROUTINE ! 534: #page ! 535: # ! 536: # SYSDT -- GET CURRENT DATE ! 537: # ! 538: .globl sysdt # define external entry point ! 539: # ! 540: # SYSDT IS USED TO OBTAIN THE CURRENT DATE. THE DATE IS ! 541: # RETURNED AS A CHARACTER STRING IN ANY FORMAT APPROPRIATE ! 542: # TO THE OPERATING SYSTEM IN USE. IT MAY ALSO CONTAIN THE ! 543: # CURRENT TIME OF DAY. SYSDT IS USED TO IMPLEMENT THE ! 544: # SNOBOL4 FUNCTION DATE. ! 545: # ! 546: # JSR SYSDT CALL TO GET DATE ! 547: # (XL) POINTER TO BLOCK CONTAINING DATE ! 548: # ! 549: # THE FORMAT OF THE BLOCK IS LIKE AN SCBLK EXCEPT THAT ! 550: # THE FIRST WORD NEED NOT BE SET. THE RESULT IS COPIED ! 551: # INTO SPITBOL DYNAMIC MEMORY ON RETURN. ! 552: #page ! 553: # ! 554: # SYSEF -- EJECT FILE ! 555: # ! 556: .globl sysef # define external entry point ! 557: # ! 558: # SYSEF IS USED TO WRITE A PAGE EJECT TO A NAMED FILE. IT ! 559: # MAY ONLY BE USED FOR FILES WHERE THIS CONCEPT MAKES ! 560: # SENSE. NOTE THAT SYSEF IS NOT NORMALLY USED FOR THE ! 561: # STANDARD OUTPUT FILE (SEE SYSEP). ! 562: # ! 563: # (WA) PTR TO FCBLK OR ZERO ! 564: # (XR) EJECT ARGUMENT (SCBLK PTR) ! 565: # JSR SYSEF CALL TO EJECT FILE ! 566: # PPM LOC RETURN HERE IF FILE DOES NOT EXIST ! 567: # PPM LOC RETURN HERE IF INAPPROPRIATE FILE ! 568: # PPM LOC RETURN HERE IF I/O ERROR ! 569: #page ! 570: # ! 571: # SYSEJ -- END OF JOB ! 572: # ! 573: .globl sysej # define external entry point ! 574: # ! 575: # SYSEJ IS CALLED ONCE AT THE END OF EXECUTION TO ! 576: # TERMINATE THE RUN. THE SIGNIFICANCE OF THE ABEND AND ! 577: # CODE VALUES IS SYSTEM DEPENDENT. IN GENERAL, THE CODE ! 578: # VALUE SHOULD BE MADE AVAILABLE FOR TESTING, AND THE ! 579: # ABEND VALUE SHOULD CAUSE SOME POST-MORTEM ACTION SUCH AS ! 580: # A DUMP. NOTE THAT SYSEJ DOES NOT RETURN TO ITS CALLER. ! 581: # SEE SYSXI FOR DETAILS OF FCBLK CHAIN ! 582: # ! 583: # (WA) VALUE OF ABEND KEYWORD ! 584: # (WB) VALUE OF CODE KEYWORD ! 585: # (XL) O OR PTR TO HEAD OF FCBLK CHAIN ! 586: # JSR SYSEJ CALL TO END JOB ! 587: # ! 588: # THE FOLLOWING SPECIAL VALUES ARE USED AS CODES IN (WB) ! 589: # 999 EXECUTION SUPPRESSED ! 590: # 998 STANDARD OUTPUT FILE FULL OR UNAVAILABLE IN A SYSXI ! 591: # LOAD MODULE. IN THESE CASES (WA) CONTAINS THE NUMBER ! 592: # OF THE STATEMENT CAUSING PREMATURE TERMINATION. ! 593: #page ! 594: # ! 595: # SYSEM -- GET ERROR MESSAGE TEXT ! 596: # ! 597: .globl sysem # define external entry point ! 598: # ! 599: # SYSEM IS USED TO OBTAIN THE TEXT OF ERR, ERB CALLS IN THE ! 600: # SOURCE PROGRAM GIVEN THE ERROR CODE NUMBER. IT IS ALLOWED ! 601: # TO RETURN A NULL STRING IF THIS FACILITY IS UNAVAILABLE. ! 602: # ! 603: # (WA) ERROR CODE NUMBER ! 604: # JSR SYSEM CALL TO GET TEXT ! 605: # (XR) TEXT OF MESSAGE ! 606: # ! 607: # THE RETURNED VALUE IS A POINTER TO A BLOCK IN SCBLK ! 608: # FORMAT EXCEPT THAT THE FIRST WORD NEED NOT BE SET. THE ! 609: # STRING IS COPIED INTO DYNAMIC MEMORY ON RETURN. ! 610: # IF THE NULL STRING IS RETURNED EITHER BECAUSE SYSEM DOES ! 611: # NOT PROVIDE ERROR MESSAGE TEXTS OR BECAUSE WA IS OUT OF ! 612: # RANGE, SPITBOL WILL PRINT THE STRING STORED IN ERRTEXT ! 613: # KEYWORD. ! 614: #page ! 615: # ! 616: # SYSEN -- ENDFILE ! 617: # ! 618: .globl sysen # define external entry point ! 619: # ! 620: # SYSEN IS USED TO IMPLEMENT THE SNOBOL4 FUNCTION ENDFILE. ! 621: # THE MEANING IS SYSTEM DEPENDENT. IN GENERAL, ENDFILE ! 622: # IMPLIES THAT NO FURTHER I/O OPERATIONS WILL BE PERFORMED, ! 623: # BUT DOES NOT GUARANTEE THIS TO BE THE CASE. THE FILE ! 624: # SHOULD BE CLOSED AFTER THE CALL, A SUBSEQUENT READ ! 625: # OR WRITE MAY REOPEN THE FILE AT THE START OR IT MAY BE ! 626: # NECESSARY TO REOPEN THE FILE VIA SYSIO. ! 627: # ! 628: # (WA) PTR TO FCBLK OR ZERO ! 629: # (XR) ENDFILE ARGUMENT (SCBLK PTR) ! 630: # JSR SYSEN CALL TO ENDFILE ! 631: # PPM LOC RETURN HERE IF FILE DOES NOT EXIST ! 632: # PPM LOC RETURN HERE IF ENDFILE NOT ALLOWED ! 633: # PPM LOC RETURN HERE IF I/O ERROR ! 634: # (WA,WB) DESTROYED ! 635: # ! 636: # THE SECOND ERROR RETURN IS USED FOR FILES FOR WHICH ! 637: # ENDFILE IS NOT PERMITTED. FOR EXAMPLE, IT MAY BE EXPECTED ! 638: # THAT THE STANDARD INPUT AND OUTPUT FILES ARE IN THIS ! 639: # CATEGORY. ! 640: #page ! 641: # ! 642: # SYSEP -- EJECT PRINTER PAGE ! 643: # ! 644: .globl sysep # define external entry point ! 645: # ! 646: # SYSEP IS CALLED TO PERFORM A PAGE EJECT ON THE STANDARD ! 647: # PRINTER OUTPUT FILE (CORRESPONDING TO SYSPR OUTPUT). ! 648: # ! 649: # JSR SYSEP CALL TO EJECT PRINTER OUTPUT ! 650: #page ! 651: # ! 652: # SYSEX -- CALL EXTERNAL FUNCTION ! 653: # ! 654: .globl sysex # define external entry point ! 655: # ! 656: # SYSEX IS CALLED TO PASS CONTROL TO AN EXTERNAL FUNCTION ! 657: # PREVIOUSLY LOADED WITH A CALL TO SYSLD. ! 658: # ! 659: # (XS) POINTER TO ARGUMENTS ON STACK ! 660: # (XL) POINTER TO CONTROL BLOCK (EFBLK) ! 661: # (WA) NUMBER OF ARGUMENTS ON STACK ! 662: # JSR SYSEX CALL TO PASS CONTROL TO FUNCTION ! 663: # PPM LOC RETURN HERE IF FUNCTION CALL FAILS ! 664: # (XS) POPPED PAST ARGUMENTS ! 665: # (XR) RESULT RETURNED ! 666: # ! 667: # THE ARGUMENTS ARE STORED ON THE STACK WITH ! 668: # THE LAST ARGUMENT AT 0(XS). ON RETURN, XS ! 669: # IS POPPED PAST THE ARGUMENTS. ! 670: # ! 671: # THE FORM OF THE ARGUMENTS AS PASSED IS THAT USED IN THE ! 672: # SPITBOL TRANSLATOR (SEE DEFINITIONS AND DATA STRUCTURES ! 673: # SECTION). THE CONTROL BLOCK FORMAT IS ALSO DESCRIBED ! 674: # (UNDER EFBLK) IN THIS SECTION. ! 675: # ! 676: # THERE ARE TWO WAYS OF RETURNING A RESULT. ! 677: # ! 678: # 1) RETURN A POINTER TO A BLOCK IN DYNAMIC STORAGE. THIS ! 679: # BLOCK MUST BE IN EXACTLY CORRECT FORMAT, INCLUDING ! 680: # THE FIRST WORD. ONLY FUNCTIONS WRITTEN WITH INTIMATE ! 681: # KNOWLEDGE OF THE SYSTEM WILL RETURN IN THIS WAY. ! 682: # ! 683: # 2) STRING, INTEGER AND REAL RESULTS MAY BE RETURNED BY ! 684: # POINTING TO A PSEUDO-BLOCK OUTSIDE DYNAMIC MEMORY. ! 685: # THIS BLOCK IS IN ICBLK, RCBLK OR SCBLK FORMAT EXCEPT ! 686: # THAT THE FIRST WORD WILL BE OVERWRITTEN ! 687: # BY A TYPE WORD ON RETURN AND SO NEED NOT ! 688: # BE CORRECTLY SET. SUCH A RESULT IS ! 689: # COPIED INTO MAIN STORAGE BEFORE PROCEEDING. ! 690: # UNCONVERTED RESULTS MAY SIMILARLY BE RETURNED IN A ! 691: # PSEUDO-BLOCK WHICH IS IN CORRECT FORMAT INCLUDING ! 692: # TYPE WORD RECOGNISABLE BY GARBAGE COLLECTOR SINCE ! 693: # BLOCK IS COPIED INTO DYNAMIC MEMORY. ! 694: #page ! 695: # ! 696: # SYSFC -- FILE CONTROL BLOCK ROUTINE ! 697: # ! 698: .globl sysfc # define external entry point ! 699: # ! 700: # SEE ALSO SYSIO ! 701: # INPUT AND OUTPUT HAVE 3 ARGUMENTS REFERRED TO AS SHOWN ! 702: # INPUT(VARIABLE NAME,FILE ARG1,FILE ARG2) ! 703: # OUTPUT(VARIABLE NAME,FILE ARG1,FILE ARG2) ! 704: # FILE ARG1 MAY BE AN INTEGER OR STRING USED TO IDENTIFY ! 705: # AN I/O CHANNEL. IT IS CONVERTED TO A STRING FOR CHECKING. ! 706: # THE EXACT SIGNIFICANCE OF FILE ARG2 ! 707: # IS NOT RIGOROUSLY PRESCRIBED BUT TO IMPROVE PORTABILITY, ! 708: # THE SCHEME DESCRIBED IN THE SPITBOL USER MANUAL ! 709: # SHOULD BE ADOPTED WHEN POSSIBLE. THE PREFERRED FORM IS ! 710: # A STRING $F$,R$R$,C$C$,I$I$,...,Z$Z$ WHERE ! 711: # $F$ IS AN OPTIONAL FILE NAME WHICH IS PLACED FIRST. ! 712: # REMAINING ITEMS MAY BE OMITTED OR INCLUDED IN ANY ORDER. ! 713: # $R$ IS MAXIMUM RECORD LENGTH ! 714: # $C$ IS A CARRIAGE CONTROL CHARACTER OR CHARACTER STRING ! 715: # $I$ IS SOME FORM OF CHANNEL IDENTIFICATION USED IN THE ! 716: # ABSENCE OF $F$ TO ASSOCIATE THE VARIABLE ! 717: # WITH A FILE ALLOCATED DYNAMICALLY BY JCL COMMANDS AT ! 718: # SPITBOL LOAD TIME. ! 719: # ,...,Z$Z$ ARE ADDITIONAL FIELDS. ! 720: # IF , (COMMA) CANNOT BE USED AS A DELIMITER, .CIOD ! 721: # SHOULD BE DEFINED TO INTRODUCE BY CONDITIONAL ASSEMBLY ! 722: # ANOTHER DELIMITER (SEE ! 723: # IODEL EQU * ! 724: # EARLY IN DEFINITIONS SECTION). ! 725: # SYSFC IS CALLED WHEN A VARIABLE IS INPUT OR OUTPUT ! 726: # ASSOCIATED TO CHECK FILE ARG1 AND FILE ARG2 AND ! 727: # TO REPORT WHETHER AN FCBLK (FILE CONTROL ! 728: # BLOCK) IS NECESSARY AND IF SO WHAT SIZE IT SHOULD BE. ! 729: # THIS MAKES IT POSSIBLE FOR SPITBOL RATHER THAN OSINT TO ! 730: # ALLOCATE SUCH A BLOCK IN DYNAMIC MEMORY IF REQUIRED ! 731: # OR ALTERNATIVELY IN STATIC MEMORY. ! 732: # THE SIGNIFICANCE OF AN FCBLK , IF ONE IS REQUESTED, IS ! 733: # ENTIRELY UP TO THE SYSTEM INTERFACE. THE ONLY RESTRICTION ! 734: # IS THAT IF THE FCBLK SHOULD APPEAR TO LIE IN DYNAMIC ! 735: # MEMORY , POINTERS TO IT SHOULD BE PROPER POINTERS TO ! 736: # THE START OF A RECOGNISABLE AND GARBAGE COLLECTABLE ! 737: # BLOCK (THIS CONDITION WILL BE MET IF SYSFC REQUESTS ! 738: # SPITBOL TO PROVIDE AN FCBLK). ! 739: # AN OPTION IS PROVIDED FOR OSINT TO RETURN A POINTER IN ! 740: # XL TO AN FCBLK WHICH IT PRIVATELY ALLOCATED. THIS PTR ! 741: # WILL BE MADE AVAILABLE WHEN I/O OCCURS LATER. ! 742: # PRIVATE FCBLKS MAY HAVE ARBITRARY CONTENTS AND SPITBOL ! 743: # STORES NOTHING IN THEM. ! 744: #page ! 745: # THE REQUESTED SIZE FOR AN FCBLK IN DYNAMIC MEMORY ! 746: # SHOULD ALLOW A 2 WORD OVERHEAD FOR BLOCK TYPE AND ! 747: # LENGTH FIELDS. INFORMATION SUBSEQUENTLY STORED IN THE ! 748: # REMAINING WORDS MAY BE ARBITRARY IF AN XNBLK (EXTERNAL ! 749: # NON-RELOCATABLE BLOCK) IS REQUESTED. IF THE REQUEST IS ! 750: # FOR AN XRBLK (EXTERNAL RELOCATABLE BLOCK) THE ! 751: # CONTENTS OF WORDS SHOULD BE COLLECTABLE (I.E. ANY ! 752: # APPARENT POINTERS INTO DYNAMIC SHOULD BE GENUINE BLOCK ! 753: # POINTERS). THESE RESTRICTIONS DO NOT APPLY IF AN FCBLK ! 754: # IS ALLOCATED OUTSIDE DYNAMIC OR IS NOT ALLOCATED AT ALL. ! 755: # IF AN FCBLK IS REQUESTED, ITS FIELDS WILL BE INITIALISED ! 756: # TO ZERO BEFORE ENTRY TO SYSIO WITH THE EXCEPTION OF ! 757: # WORDS 0 AND 1 IN WHICH THE BLOCK TYPE AND LENGTH ! 758: # FIELDS ARE PLACED FOR FCBLKS IN DYNAMIC MEMORY ONLY. ! 759: # FOR THE POSSIBLE USE OF SYSEJ AND SYSXI, IF FCBLKS ! 760: # ARE USED, A CHAIN IS BUILT SO THAT THEY MAY ALL BE ! 761: # FOUND - SEE SYSXI FOR DETAILS. ! 762: # IF BOTH FILE ARG1 AND FILE ARG2 ARE NULL, CALLS OF SYSFC ! 763: # AND SYSIO ARE OMITTED. ! 764: # IF FILE ARG1 IS NULL (STANDARD INPUT/OUTPUT FILE), SYSFC ! 765: # IS CALLED TO CHECK NON-NULL FILE ARG2 BUT ANY REQUEST ! 766: # FOR AN FCBLK WILL BE IGNORED, SINCE SPITBOL HANDLES THE ! 767: # STANDARD FILES SPECIALLY AND CANNOT READILY KEEP FCBLK ! 768: # POINTERS FOR THEM. ! 769: # FILEARG1 IS TYPE CHECKED BY SPITBOL SO FURTHER CHECKING ! 770: # MAY BE UNNECCESSARY IN MANY IMPLEMENTATIONS. ! 771: # FILE ARG2 IS PASSED SO THAT SYSFC MAY ANALYSE AND ! 772: # CHECK IT. HOWEVER TO ASSIST IN THIS, SPITBOL ALSO PASSES ! 773: # ON THE STACK THE COMPONENTS OF THIS ARGUMENT WITH ! 774: # FILE NAME, $F$ (OTHERWISE NULL) EXTRACTED AND STACKED ! 775: # FIRST. ! 776: # THE OTHER FIELDS, IF ANY, ARE EXTRACTED AS SUBSTRINGS, ! 777: # POINTERS TO THEM ARE STACKED AND A COUNT OF ALL ITEMS ! 778: # STACKED IS PLACED IN WC. IF AN FCBLK WAS EARLIER ! 779: # ALLOCATED AND POINTED TO VIA FILE ARG1, SYSFC IS ALSO ! 780: # PASSED A POINTER TO THIS FCBLK. ! 781: # ! 782: # (XL) FILE ARG1 SCBLK PTR (2ND ARG) ! 783: # (XR) FILEARG2 (3RD ARG) OR NULL ! 784: # -(XS)...-(XS) SCBLKS FOR $F$,$R$,$C$,... ! 785: # (WC) NO. OF STACKED SCBLKS ABOVE ! 786: # (WA) EXISTING FILE ARG1 FCBLK PTR OR 0 ! 787: # (WB) 0/3 FOR INPUT/OUTPUT ASSOCN ! 788: # JSR SYSFC CALL TO CHECK NEED FOR FCBLK ! 789: # PPM LOC INVALID FILE ARGUMENT ! 790: # (XS) POPPED (WC) TIMES ! 791: # (WA NON ZERO) BYTE SIZE OF REQUESTED FCBLK ! 792: # (WA=0,XL NON ZERO) PRIVATE FCBLK PTR IN XL ! 793: # (WA=XL=0) NO FCBLK WANTED, NO PRIVATE FCBLK ! 794: # (WC) 0/1/2 REQUEST ALLOC OF XRBLK/XNBLK ! 795: # /STATIC BLOCK FOR USE AS FCBLK ! 796: # (WB) DESTROYED ! 797: #page ! 798: # ! 799: # SYSHS -- GIVE ACCESS TO HOST COMPUTER FEATURES ! 800: # ! 801: .globl syshs # define external entry point ! 802: # ! 803: # PROVIDES MEANS FOR IMPLEMENTING SPECIAL FEATURES ! 804: # ON DIFFERENT HOST COMPUTERS. THE ONLY DEFINED ENTRY IS ! 805: # THAT WHERE ALL ARGUMENTS ARE NULL IN WHICH CASE SYSHS ! 806: # RETURNS AN SCBLK CONTAINING NAME OF COMPUTER, ! 807: # NAME OF OPERATING SYSTEM AND NAME OF SITE SEPARATED BY ! 808: # COLONS. THE SCBLK NEED NOT HAVE A CORRECT FIRST FIELD ! 809: # AS THIS IS SUPPLIED ON COPYING STRING TO DYNAMIC MEMORY. ! 810: # SPITBOL DOES NO ARGUMENT CHECKING BUT DOES PROVIDE A ! 811: # SINGLE ERROR RETURN FOR ARGUMENTS CHECKED AS ERRONEOUS ! 812: # BY OSINT. IT ALSO PROVIDES A SINGLE EXECUTION ERROR ! 813: # RETURN. IF THESE ARE INADEQUATE, USE MAY BE MADE OF THE ! 814: # MINIMAL ERROR SECTION DIRECT AS DESCRIBED IN MINIMAL ! 815: # DOCUMENTATION, SECTION 10. ! 816: # SEVERAL NON-ERROR RETURNS ARE PROVIDED. THE FIRST ! 817: # CORRESPONDS TO THE DEFINED ENTRY OR, FOR IMPLEMENTATION ! 818: # DEFINED ENTRIES, ANY STRING MAY BE RETURNED. THE OTHERS ! 819: # PERMIT RESPECTIVELY, RETURN A NULL RESULT, RETURN WITH A ! 820: # RESULT TO BE STACKED WHICH IS POINTED AT BY XR, AND A ! 821: # RETURN CAUSING SPITBOL STATEMENT FAILURE. IF A RETURNED ! 822: # RESULT IS IN DYNAMIC MEMORY IT MUST OBEY GARBAGE ! 823: # COLLECTOR RULES. THE ONLY RESULTS COPIED ON RETURN ! 824: # ARE STRINGS RETURNED VIA PPM LOC3 RETURN. ! 825: # ! 826: # (WA) ARGUMENT 1 ! 827: # (XL) ARGUMENT 2 ! 828: # (XR) ARGUMENT 3 ! 829: # JSR SYSHS CALL TO GET HOST INFORMATION ! 830: # PPM LOC1 ERRONEOUS ARG ! 831: # PPM LOC2 EXECUTION ERROR ! 832: # PPM LOC3 SCBLK PTR IN XL OR 0 IF UNAVAILABLE ! 833: # PPM LOC4 RETURN A NULL RESULT ! 834: # PPM LOC5 RETURN RESULT IN XR ! 835: # PPM LOC6 CAUSE STATEMENT FAILURE ! 836: #page ! 837: # ! 838: # SYSID -- RETURN SYSTEM IDENTIFICATION ! 839: # ! 840: .globl sysid # define external entry point ! 841: # ! 842: # THIS ROUTINE SHOULD RETURN STRINGS TO HEAD THE STANDARD ! 843: # PRINTER OUTPUT. THE FIRST STRING WILL BE APPENDED TO ! 844: # A HEADING LINE OF THE FORM ! 845: # MACRO SPITBOL VERSION V.V ! 846: # SUPPLIED BY SPITBOL ITSELF. V.V ARE DIGITS GIVING THE ! 847: # MAJOR VERSION NUMBER AND GENERALLY AT LEAST A MINOR ! 848: # VERSION NUMBER RELATING TO OSINT SHOULD BE SUPPLIED TO ! 849: # GIVE SAY ! 850: # MACRO SPITBOL VERSION V.V(M.M) ! 851: # THE SECOND STRING SHOULD IDENTIFY AT LEAST THE MACHINE ! 852: # AND OPERATING SYSTEM. PREFERABLY IT SHOULD INCLUDE ! 853: # THE DATE AND TIME OF THE RUN. ! 854: # OPTIONALLY THE STRINGS MAY INCLUDE SITE NAME OF THE ! 855: # THE IMPLEMENTOR AND/OR MACHINE ON WHICH RUN TAKES PLACE, ! 856: # UNIQUE SITE OR COPY NUMBER AND OTHER INFORMATION AS ! 857: # APPROPRIATE WITHOUT MAKING IT SO LONG AS TO BE A ! 858: # NUISANCE TO USERS. ! 859: # THE FIRST WORDS OF THE SCBLKS POINTED AT NEED NOT BE ! 860: # CORRECTLY SET. ! 861: # ! 862: # JSR SYSID CALL FOR SYSTEM IDENTIFICATION ! 863: # (XR) SCBLK PTR FOR ADDITION TO HEADER ! 864: # (XL) PTR TO SECOND HEADER SCBLK ! 865: #page ! 866: # ! 867: # SYSIL -- GET INPUT RECORD LENGTH ! 868: # ! 869: .globl sysil # define external entry point ! 870: # ! 871: # SYSIL IS USED TO GET THE LENGTH OF THE NEXT INPUT RECORD ! 872: # FROM A FILE PREVIOUSLY INPUT ASSOCIATED WITH A SYSIO ! 873: # CALL. THE LENGTH RETURNED IS USED TO ESTABLISH A BUFFER ! 874: # FOR A SUBSEQUENT SYSIN CALL. ! 875: # ! 876: # (WA) PTR TO FCBLK OR ZERO ! 877: # JSR SYSIL CALL TO GET RECORD LENGTH ! 878: # (WA) LENGTH OR ZERO IF FILE CLOSED ! 879: # ! 880: # NO HARM IS DONE IF THE VALUE RETURNED IS TOO LONG SINCE ! 881: # UNUSED SPACE WILL BE RECLAIMED AFTER THE SYSIN CALL. ! 882: # ! 883: # NOTE THAT IT IS THE SYSIL CALL (NOT THE SYSIO CALL) WHICH ! 884: # CAUSES THE FILE TO BE OPENED AS REQUIRED FOR THE FIRST ! 885: # RECORD INPUT FROM THE FILE. ! 886: #page ! 887: # ! 888: # SYSIN -- READ INPUT RECORD ! 889: # ! 890: .globl sysin # define external entry point ! 891: # ! 892: # SYSIN IS USED TO READ A RECORD FROM THE FILE WHICH WAS ! 893: # REFERENCED IN A PRIOR CALL TO SYSIL (I.E. THESE CALLS ! 894: # ALWAYS OCCUR IN PAIRS). THE BUFFER PROVIDED IS AN ! 895: # SCBLK FOR A STRING OF LENGTH SET FROM THE SYSIL CALL. ! 896: # IF THE ACTUAL LENGTH READ IS LESS THAN THIS, THE LENGTH ! 897: # FIELD OF THE SCBLK MUST BE MODIFIED BEFORE RETURNING ! 898: # UNLESS BUFFER IS RIGHT PADDED WITH ZEROES. ! 899: # IT IS ALSO PERMISSIBLE TO TAKE ANY OF THE ALTERNATIVE ! 900: # RETURNS AFTER SCBLK LENGTH HAS BEEN MODIFIED. ! 901: # ! 902: # (WA) PTR TO FCBLK OR ZERO ! 903: # (XR) POINTER TO BUFFER (SCBLK PTR) ! 904: # JSR SYSIN CALL TO READ RECORD ! 905: # PPM LOC ENDFILE OR NO I/P FILE AFTER SYSXI ! 906: # PPM LOC RETURN HERE IF I/O ERROR ! 907: # PPM LOC RETURN HERE IF RECORD FORMAT ERROR ! 908: # (WA,WB,WC) DESTROYED ! 909: #page ! 910: # ! 911: # SYSIO -- INPUT/OUTPUT FILE ASSOCIATION ! 912: # ! 913: .globl sysio # define external entry point ! 914: # ! 915: # SEE ALSO SYSFC. ! 916: # SYSIO IS CALLED IN RESPONSE TO A SNOBOL4 INPUT OR OUTPUT ! 917: # FUNCTION CALL EXCEPT WHEN FILE ARG1 AND FILE ARG2 ! 918: # ARE BOTH NULL. ! 919: # ITS CALL ALWAYS FOLLOWS IMMEDIATELY AFTER A CALL ! 920: # OF SYSFC. IF SYSFC REQUESTED ALLOCATION ! 921: # OF AN FCBLK, ITS ADDRESS WILL BE IN WA. ! 922: # FOR INPUT FILES, NON-ZERO VALUES OF $R$ SHOULD BE ! 923: # COPIED TO WC FOR USE IN ALLOCATING INPUT BUFFERS. IF $R$ ! 924: # IS DEFAULTED OR NOT IMPLEMENTED, WC SHOULD BE ZEROISED. ! 925: # ONCE A FILE HAS BEEN OPENED, SUBSEQUENT INPUT(),OUTPUT() ! 926: # CALLS IN WHICH THE SECOND ARGUMENT IS IDENTICAL WITH THAT ! 927: # IN A PREVIOUS CALL, MERELY ASSOCIATE THE ADDITIONAL ! 928: # VARIABLE NAME (FIRST ARGUMENT) TO THE FILE AND DO NOT ! 929: # RESULT IN RE-OPENING THE FILE. ! 930: # IN SUBSEQUENT ASSOCIATED ACCESSES TO THE FILE A POINTER ! 931: # TO ANY FCBLK ALLOCATED WILL BE MADE AVAILABLE. ! 932: # ! 933: # (XL) FILE ARG1 SCBLK PTR (2ND ARG) ! 934: # (XR) FILE ARG2 SCBLK PTR (3RD ARG) ! 935: # (WA) FCBLK PTR (0 IF NONE) ! 936: # (WB) 0 FOR INPUT, 3 FOR OUTPUT ! 937: # JSR SYSIO CALL TO ASSOCIATE FILE ! 938: # PPM LOC RETURN HERE IF FILE DOES NOT EXIST ! 939: # PPM LOC RETURN IF INPUT/OUTPUT NOT ALLOWED ! 940: # (XL) FCBLK POINTER (0 IF NONE) ! 941: # (WC) 0 (FOR DEFAULT) OR MAX RECORD LNGTH ! 942: # (WA,WB) DESTROYED ! 943: # ! 944: # THE SECOND ERROR RETURN IS USED IF THE FILE NAMED EXISTS ! 945: # BUT INPUT/OUTPUT FROM THE FILE IS NOT ALLOWED. FOR ! 946: # EXAMPLE, THE STANDARD OUTPUT FILE MAY BE IN THIS CATEGORY ! 947: # AS REGARDS INPUT ASSOCIATION. ! 948: #page ! 949: # ! 950: # SYSLD -- LOAD EXTERNAL FUNCTION ! 951: # ! 952: .globl sysld # define external entry point ! 953: # ! 954: # SYSLD IS CALLED IN RESPONSE TO THE USE OF THE SNOBOL4 ! 955: # LOAD FUNCTION. THE NAMED FUNCTION IS LOADED (WHATEVER ! 956: # THIS MEANS), AND A POINTER IS RETURNED. THE POINTER WILL ! 957: # BE USED ON SUBSEQUENT CALLS TO THE FUNCTION (SEE SYSEX). ! 958: # ! 959: # (XR) POINTER TO FUNCTION NAME (SCBLK) ! 960: # (XL) POINTER TO LIBRARY NAME (SCBLK) ! 961: # JSR SYSLD CALL TO LOAD FUNCTION ! 962: # PPM LOC RETURN HERE IF FUNC DOES NOT EXIST ! 963: # PPM LOC RETURN HERE IF I/O ERROR ! 964: # (XR) POINTER TO LOADED CODE ! 965: # ! 966: # THE SIGNIFICANCE OF THE POINTER RETURNED IS UP TO THE ! 967: # SYSTEM INTERFACE ROUTINE. THE ONLY RESTRICTION IS THAT ! 968: # IF THE POINTER IS WITHIN DYNAMIC STORAGE, IT MUST BE ! 969: # A PROPER BLOCK POINTER. ! 970: #page ! 971: # ! 972: # SYSMM -- GET MORE MEMORY ! 973: # ! 974: .globl sysmm # define external entry point ! 975: # ! 976: # SYSMM IS CALLED IN AN ATTEMPT TO ALLOCATE MORE DYNAMIC ! 977: # MEMORY. THIS MEMORY MUST BE ALLOCATED CONTIGUOUSLY WITH ! 978: # THE CURRENT DYNAMIC DATA AREA. ! 979: # ! 980: # THE AMOUNT ALLOCATED IS UP TO THE SYSTEM TO DECIDE. ANY ! 981: # VALUE IS ACCEPTABLE INCLUDING ZERO IF ALLOCATION IS ! 982: # IMPOSSIBLE. ! 983: # ! 984: # JSR SYSMM CALL TO GET MORE MEMORY ! 985: # (XR) NUMBER OF ADDITIONAL WORDS OBTAINED ! 986: #page ! 987: # ! 988: # SYSMX -- SUPPLY MXLEN ! 989: # ! 990: .globl sysmx # define external entry point ! 991: # ! 992: # BECAUSE OF THE METHOD OF GARBAGE COLLECTION, NO SPITBOL ! 993: # OBJECT IS ALLOWED TO OCCUPY MORE BYTES OF MEMORY THAN ! 994: # THE INTEGER GIVING THE LOWEST ADDRESS OF DYNAMIC ! 995: # (GARBAGE COLLECTABLE) MEMORY. MXLEN IS THE NAME USED TO ! 996: # REFER TO THIS MAXIMUM LENGTH OF AN OBJECT AND FOR MOST ! 997: # USERS OF MOST IMPLEMENTATIONS, PROVIDED DYNAMIC MEMORY ! 998: # STARTS AT AN ADDRESS OF AT LEAST A FEW THOUSAND WORDS, ! 999: # THERE IS NO PROBLEM. ! 1000: # IF THE DEFAULT STARTING ADDRESS IS LESS THAN SAY 10000 OR ! 1001: # 20000, THEN A LOAD TIME OPTION SHOULD BE PROVIDED WHERE A ! 1002: # USER CAN REQUEST THAT HE BE ABLE TO CREATE LARGER ! 1003: # OBJECTS. THIS ROUTINE INFORMS SPITBOL OF THIS REQUEST IF ! 1004: # ANY. THE VALUE RETURNED IS EITHER AN INTEGER ! 1005: # REPRESENTING THE DESIRED VALUE OF MXLEN (AND HENCE THE ! 1006: # MINIMUM DYNAMIC STORE ADDRESS WHICH MAY RESULT IN ! 1007: # NON-USE OF SOME STORE) OR ZERO IF A DEFAULT IS ACCEPTABLE ! 1008: # IN WHICH MXLEN IS SET TO THE LOWEST ADDRESS ALLOCATED ! 1009: # TO DYNAMIC STORE BEFORE COMPILATION STARTS. ! 1010: # IF A NON-ZERO VALUE IS RETURNED, THIS IS USED FOR KEYWORD ! 1011: # MAXLNGTH. OTHERWISE THE INITIAL LOW ADDRESS OF DYNAMIC ! 1012: # MEMORY IS USED FOR THIS KEYWORD. ! 1013: # ! 1014: # JSR SYSMX CALL TO GET MXLEN ! 1015: # (WA) EITHER MXLEN OR 0 FOR DEFAULT ! 1016: #page ! 1017: # ! 1018: # SYSOU -- OUTPUT RECORD ! 1019: # ! 1020: .globl sysou # define external entry point ! 1021: # ! 1022: # SYSOU IS USED TO WRITE A RECORD TO A FILE PREVIOUSLY ! 1023: # ASSOCIATED WITH A SYSIO CALL. ! 1024: # ! 1025: # (WA) PTR TO FCBLK OR ZERO ! 1026: # (XR) RECORD TO BE WRITTEN (SCBLK) ! 1027: # JSR SYSOU CALL TO OUTPUT RECORD ! 1028: # PPM LOC FILE FULL OR NO FILE AFTER SYSXI ! 1029: # PPM LOC RETURN HERE IF I/O ERROR ! 1030: # (WA,WB,WC) DESTROYED ! 1031: # ! 1032: # NOTE THAT IT IS THE SYSOU CALL (NOT THE SYSIO CALL) WHICH ! 1033: # CAUSES THE FILE TO BE OPENED AS REQUIRED FOR THE FIRST ! 1034: # RECORD OUTPUT TO THE FILE. ! 1035: #page ! 1036: # ! 1037: # SYSPI -- PRINT ON INTERACTIVE CHANNEL ! 1038: # ! 1039: .globl syspi # define external entry point ! 1040: # ! 1041: # IF SPITBOL IS RUN FROM AN ONLINE TERMINAL, OSINT CAN ! 1042: # REQUEST THAT MESSAGES SUCH AS COPIES OF COMPILATION ! 1043: # ERRORS BE SENT TO THE TERMINAL (SEE SYSPP). IF RELEVANT ! 1044: # REPLY WAS MADE BY SYSPP THEN SYSPI IS CALLED TO SEND SUCH ! 1045: # MESSAGES TO THE INTERACTIVE CHANNEL. ! 1046: # SYSPI IS ALSO USED FOR SENDING OUTPUT TO THE TERMINAL ! 1047: # THROUGH THE SPECIAL VARIABLE NAME, TERMINAL. ! 1048: # ! 1049: # (XR) PTR TO LINE BUFFER (SCBLK) ! 1050: # (WA) LINE LENGTH ! 1051: # JSR SYSPI CALL TO PRINT LINE ! 1052: # PPM LOC FAILURE RETURN ! 1053: # (WA,WB) DESTROYED ! 1054: #page ! 1055: # ! 1056: # SYSPP -- OBTAIN PRINT PARAMETERS ! 1057: # ! 1058: .globl syspp # define external entry point ! 1059: # ! 1060: # SYSPP IS CALLED ONCE DURING COMPILATION TO OBTAIN ! 1061: # PARAMETERS REQUIRED FOR CORRECT PRINTED OUTPUT FORMAT ! 1062: # AND TO SELECT OTHER OPTIONS. IT MAY ALSO BE CALLED AGAIN ! 1063: # AFTER SYSXI WHEN A LOAD MODULE IS RESUMED. IN THIS ! 1064: # CASE THE VALUE RETURNED IN WA MAY BE LESS THAN OR EQUAL ! 1065: # TO THAT RETURNED IN INITIAL CALL BUT MAY NOT BE ! 1066: # GREATER. ! 1067: # THE INFORMATION RETURNED IS - ! 1068: # 1. LINE LENGTH IN CHARS FOR STANDARD PRINT FILE ! 1069: # 2. NO OF LINES/PAGE. 0 IS PREFERABLE FOR A NON-PAGED ! 1070: # DEVICE (E.G. ONLINE TERMINAL) IN WHICH CASE LISTING ! 1071: # PAGE THROWS ARE SUPPRESSED AND PAGE HEADERS ! 1072: # RESULTING FROM -TITLE,-STITL LINES ARE KEPT SHORT. ! 1073: # 3. AN INITIAL -NOLIST OPTION TO SUPPRESS LISTING UNLESS ! 1074: # THE PROGRAM CONTAINS AN EXPLICIT -LIST. ! 1075: # 4. OPTIONS TO SUPPRESS LISTING OF COMPILATION AND/OR ! 1076: # EXECUTION STATS (USEFUL FOR ESTABLISHED PROGRAMS) - ! 1077: # COMBINED WITH 3. GIVES POSSIBILITY OF LISTING ! 1078: # FILE NEVER BEING OPENED. ! 1079: # 5. OPTION TO HAVE COPIES OF ERRORS SENT TO AN ! 1080: # INTERACTIVE CHANNEL IN ADDITION TO STANDARD PRINTER. ! 1081: # 6. OPTION TO KEEP PAGE HEADERS SHORT (E.G. IF LISTING ! 1082: # TO AN ONLINE TERMINAL). ! 1083: # 7. AN OPTION TO CHOOSE EXTENDED OR COMPACT LISTING ! 1084: # FORMAT. IN THE FORMER A PAGE EJECT AND IN THE LATTER ! 1085: # A FEW LINE FEEDS PRECEDE THE PRINTING OF EACH ! 1086: # OF-- LISTING, COMPILATION STATISTICS, EXECUTION ! 1087: # OUTPUT AND EXECUTION STATISTICS. ! 1088: # 8. AN OPTION TO SUPPRESS EXECUTION AS THOUGH A ! 1089: # -NOEXECUTE CARD WERE SUPPLIED. ! 1090: # 9. AN OPTION TO REQUEST THAT NAME /TERMINAL/ BE PRE- ! 1091: # ASSOCIATED TO AN ONLINE TERMINAL VIA SYSPI AND SYSRI ! 1092: # 10. AN INTERMEDIATE (STANDARD) LISTING OPTION REQUIRING ! 1093: # THAT PAGE EJECTS OCCUR IN SOURCE LISTINGS. REDUNDANT ! 1094: # IF EXTENDED OPTION CHOSEN BUT PARTIALLY EXTENDS ! 1095: # COMPACT OPTION. ! 1096: # 11. OPTION TO SUPPRESS SYSID IDENTIFICATION. ! 1097: # ! 1098: # JSR SYSPP CALL TO GET PRINT PARAMETERS ! 1099: # (WA) PRINT LINE LENGTH IN CHARS ! 1100: # (WB) NUMBER OF LINES/PAGE ! 1101: # (WC) BITS VALUE ...JIHGFEDCBA WHERE ! 1102: # A = 1 TO SEND ERROR COPY TO INT.CH. ! 1103: # B = 1 MEANS STD PRINTER IS INT. CH. ! 1104: # C = 1 FOR -NOLIST OPTION ! 1105: # D = 1 TO SUPPRESS COMPILN. STATS ! 1106: # E = 1 TO SUPPRESS EXECN. STATS ! 1107: # F = 1/0 FOR EXTNDED/COMPACT LISTING ! 1108: # G = 1 FOR -NOEXECUTE ! 1109: # H = 1 PRE-ASSOCIATE /TERMINAL/ ! 1110: # I = 1 FOR STANDARD LISTING OPTION. ! 1111: # J = 1 SUPPRESSES LISTING HEADER ! 1112: #page ! 1113: # ! 1114: # SYSPR -- PRINT LINE ON STANDARD OUTPUT FILE ! 1115: # ! 1116: .globl syspr # define external entry point ! 1117: # ! 1118: # SYSPR IS USED TO PRINT A SINGLE LINE ON THE STANDARD ! 1119: # OUTPUT FILE. ! 1120: # ! 1121: # (XR) POINTER TO LINE BUFFER (SCBLK) ! 1122: # (WA) LINE LENGTH ! 1123: # JSR SYSPR CALL TO PRINT LINE ! 1124: # PPM LOC TOO MUCH O/P OR NO FILE AFTER SYSXI ! 1125: # (WA,WB) DESTROYED ! 1126: # ! 1127: # THE BUFFER POINTED TO IS THE LENGTH OBTAINED FROM THE ! 1128: # SYSPP CALL AND IS FILLED OUT WITH TRAILING BLANKS. THE ! 1129: # VALUE IN WA IS THE ACTUAL LINE LENGTH WHICH MAY BE LESS ! 1130: # THAN THE MAXIMUM LINE LENGTH POSSIBLE. THERE IS NO SPACE ! 1131: # CONTROL ASSOCIATED WITH THE LINE, ALL LINES ARE PRINTED ! 1132: # SINGLE SPACED. NOTE THAT NULL LINES (WA=0) ARE POSSIBLE ! 1133: # IN WHICH CASE A BLANK LINE IS TO BE PRINTED. ! 1134: # ! 1135: # THE ERROR EXIT IS USED FOR SYSTEMS WHICH LIMIT THE AMOUNT ! 1136: # OF PRINTED OUTPUT. IF POSSIBLE, PRINTING SHOULD BE ! 1137: # PERMITTED AFTER THIS CONDITION HAS BEEN SIGNALLED ONCE TO ! 1138: # ALLOW FOR DUMP AND OTHER DIAGNOSTIC INFORMATION. ! 1139: # ASSUMING THIS TO BE POSSIBLE, SPITBOL MAY MAKE MORE SYSPR ! 1140: # CALLS. IF THE ERROR RETURN OCCURS ANOTHER TIME, EXECUTION ! 1141: # IS TERMINATED BY A CALL OF SYSEJ WITH ENDING CODE 998. ! 1142: #page ! 1143: # ! 1144: # SYSRD -- READ RECORD FROM STANDARD INPUT FILE ! 1145: # ! 1146: .globl sysrd # define external entry point ! 1147: # ! 1148: # SYSRD IS USED TO READ A RECORD FROM THE STANDARD INPUT ! 1149: # FILE. THE BUFFER PROVIDED IS AN SCBLK FOR A STRING THE ! 1150: # LENGTH OF WHICH IN CHARACTERS IS GIVEN IN WC, THIS ! 1151: # CORRESPONDING TO THE MAXIMUM LENGTH OF STRING WHICH ! 1152: # SPITBOL IS PREPARED TO RECEIVE. AT COMPILE TIME IT ! 1153: # CORRESPONDS TO XXX IN THE MOST RECENT -INXXX CARD ! 1154: # (DEFAULT 72) AND AT EXECUTION TIME TO THE MOST RECENT ! 1155: # ,R$R$ (RECORD LENGTH) IN THE THIRD ARG OF AN INPUT() ! 1156: # STATEMENT FOR THE STANDARD INPUT FILE (DEFAULT 80). ! 1157: # IF FEWER THAN (WC) CHARACTERS ARE READ, THE LENGTH ! 1158: # FIELD OF THE SCBLK MUST BE ADJUSTED BEFORE RETURNING ! 1159: # UNLESS THE BUFFER IS RIGHT PADDED WITH ZEROES. ! 1160: # IT IS ALSO PERMISSIBLE TO TAKE THE ALTERNATIVE RETURN ! 1161: # AFTER SUCH AN ADJUSTMENT HAS BEEN MADE. ! 1162: # SPITBOL MAY CONTINUE TO MAKE CALLS AFTER AN ENDFILE ! 1163: # RETURN SO THIS ROUTINE SHOULD BE PREPARED TO MAKE ! 1164: # REPEATED ENDFILE RETURNS. ! 1165: # ! 1166: # (XR) POINTER TO BUFFER (SCBLK PTR) ! 1167: # (WC) LENGTH OF BUFFER IN CHARACTERS ! 1168: # JSR SYSRD CALL TO READ LINE ! 1169: # PPM LOC ENDFILE OR NO I/P FILE AFTER SYSXI ! 1170: # (WA,WB,WC) DESTROYED ! 1171: #page ! 1172: # ! 1173: # SYSRI -- READ RECORD FROM INTERACTIVE CHANNEL ! 1174: # ! 1175: .globl sysri # define external entry point ! 1176: # ! 1177: # READS A RECORD FROM ONLINE TERMINAL FOR SPITBOL VARIABLE, ! 1178: # TERMINAL. IF ONLINE TERMINAL IS UNAVAILABLE THEN CODE THE ! 1179: # ENDFILE RETURN ONLY. ! 1180: # THE BUFFER PROVIDED IS OF LENGTH 120 CHARACTERS. SYSRI ! 1181: # SHOULD REPLACE THE COUNT IN THE SECOND WORD OF THE SCBLK ! 1182: # BY THE ACTUAL CHARACTER COUNT UNLESS BUFFER IS RIGHT ! 1183: # PADDED WITH ZEROES. ! 1184: # IT IS ALSO PERMISSIBLE TO TAKE THE ALTERNATIVE ! 1185: # RETURN AFTER ADJUSTING THE COUNT. ! 1186: # THE END OF FILE RETURN MAY BE USED IF THIS MAKES ! 1187: # SENSE ON THE TARGET MACHINE (E.G. IF THERE IS AN ! 1188: # EOF CHARACTER.) ! 1189: # ! 1190: # (XR) PTR TO 120 CHAR BUFFER (SCBLK PTR) ! 1191: # JSR SYSRI CALL TO READ LINE FROM TERMINAL ! 1192: # PPM LOC END OF FILE RETURN ! 1193: # (WA,WB,WC) MAY BE DESTROYED ! 1194: #page ! 1195: # ! 1196: # SYSRW -- REWIND FILE ! 1197: # ! 1198: .globl sysrw # define external entry point ! 1199: # ! 1200: # SYSRW IS USED TO REWIND A FILE I.E. REPOSITION THE FILE ! 1201: # AT THE START BEFORE THE FIRST RECORD. THE FILE SHOULD BE ! 1202: # CLOSED AND THE NEXT READ OR WRITE CALL WILL OPEN THE ! 1203: # FILE AT THE START. ! 1204: # ! 1205: # (WA) PTR TO FCBLK OR ZERO ! 1206: # (XR) REWIND ARG (SCBLK PTR) ! 1207: # JSR SYSRW CALL TO REWIND FILE ! 1208: # PPM LOC RETURN HERE IF FILE DOES NOT EXIST ! 1209: # PPM LOC RETURN HERE IF REWIND NOT ALLOWED ! 1210: # PPM LOC RETURN HERE IF I/O ERROR ! 1211: #page ! 1212: # ! 1213: # SYSST -- SET FILE POINTER ! 1214: # ! 1215: .globl sysst # define external entry point ! 1216: # ! 1217: # SYSST IS CALLED TO CHANGE THE POSITION OF A FILE ! 1218: # POINTER. THIS IS ACCOMPLISHED IN A SYSTEM DEPENDENT ! 1219: # MANNER, AND THUS THE 2ND AND 3RD ARGUMENTS ARE PASSED ! 1220: # UNCONVERTED. ! 1221: # ! 1222: # (WA) FCBLK POINTER ! 1223: # (WB) 2ND ARGUMENT ! 1224: # (WC) 3RD ARGUMENT ! 1225: # JSR SYSST CALL TO SET FILE POINTER ! 1226: # PPM LOC RETURN HERE IF INVALID 2ND ARG ! 1227: # PPM LOC RETURN HERE IF INVALID 3RD ARG ! 1228: # PPM LOC RETURN HERE IF FILE DOES NOT EXIST ! 1229: # PPM LOC RETURN HERE IF SET NOT ALLOWED ! 1230: # PPM LOC RETURN HERE IF I/O ERROR ! 1231: # ! 1232: #page ! 1233: # ! 1234: # SYSTM -- GET EXECUTION TIME SO FAR ! 1235: # ! 1236: .globl systm # define external entry point ! 1237: # ! 1238: # SYSTM IS USED TO OBTAIN THE AMOUNT OF EXECUTION TIME ! 1239: # USED SO FAR SINCE SPITBOL WAS GIVEN CONTROL. THE UNITS ! 1240: # ARE DESCRIBED AS MILLISECONDS IN THE SPITBOL OUTPUT, BUT ! 1241: # THE EXACT MEANING IS SYSTEM DEPENDENT. WHERE APPROPRIATE, ! 1242: # THIS VALUE SHOULD RELATE TO PROCESSOR RATHER THAN CLOCK ! 1243: # TIMING VALUES. ! 1244: # ! 1245: # JSR SYSTM CALL TO GET TIMER VALUE ! 1246: # (IA) TIME SO FAR IN MILLISECONDS ! 1247: #page ! 1248: # ! 1249: # SYSTT -- TRACE TOGGLE ! 1250: # ! 1251: .globl systt # define external entry point ! 1252: # ! 1253: # CALLED BY SPITBOL FUNCTION TRACE() WITH NO ARGS TO ! 1254: # TOGGLE THE SYSTEM TRACE SWITCH. THIS PERMITS TRACING OF ! 1255: # LABELS IN SPITBOL CODE TO BE TURNED ON OR OFF. ! 1256: # ! 1257: # JSR SYSTT CALL TO TOGGLE TRACE SWITCH ! 1258: #page ! 1259: # ! 1260: # SYSUL -- UNLOAD EXTERNAL FUNCTION ! 1261: # ! 1262: .globl sysul # define external entry point ! 1263: # ! 1264: # SYSUL IS USED TO UNLOAD A FUNCTION PREVIOUSLY ! 1265: # LOADED WITH A CALL TO SYSLD. ! 1266: # ! 1267: # (XR) PTR TO CONTROL BLOCK (EFBLK) ! 1268: # JSR SYSUL CALL TO UNLOAD FUNCTION ! 1269: # ! 1270: # THE FUNCTION CANNOT BE CALLED FOLLOWING A SYSUL CALL ! 1271: # UNTIL ANOTHER SYSLD CALL IS MADE FOR THE SAME FUNCTION. ! 1272: # ! 1273: # THE EFBLK CONTAINS THE FUNCTION CODE POINTER AND ALSO A ! 1274: # POINTER TO THE VRBLK CONTAINING THE FUNCTION NAME (SEE ! 1275: # DEFINITIONS AND DATA STRUCTURES SECTION). ! 1276: #page ! 1277: # ! 1278: # SYSXI -- EXIT TO PRODUCE LOAD MODULE ! 1279: # ! 1280: .globl sysxi # define external entry point ! 1281: # ! 1282: # WHEN SYSXI IS CALLED, XL CONTAINS EITHER A STRING POINTER ! 1283: # OR ZERO. IN THE FORMER CASE, THE STRING GIVES THE ! 1284: # CHARACTER NAME OF A PROGRAM. THE INTENTION IS THAT ! 1285: # SPITBOL EXECUTION SHOULD BE TERMINATED FORTHWITH AND ! 1286: # THE NAMED PROGRAM LOADED AND EXECUTED. THIS TYPE OF CHAIN ! 1287: # EXECUTION IS VERY SYSTEM DEPENDENT AND IMPLEMENTORS MAY ! 1288: # CHOOSE TO OMIT IT OR FIND IT IMPOSSIBLE TO PROVIDE. ! 1289: # IF (XL) IS ZERO,IA CONTAINS ONE OF THE FOLLOWING INTEGERS ! 1290: # ! 1291: # -1, -2, -3 ! 1292: # CREATE IF POSSIBLE A LOAD MODULE CONTAINING ONLY THE ! 1293: # IMPURE AREA OF MEMORY WHICH NEEDS TO BE LOADED WITH ! 1294: # A COMPATIBLE PURE SEGMENT FOR SUBSEQUENT EXECUTIONS. ! 1295: # VERSION NUMBERS TO CHECK COMPATIBILITY SHOULD BE ! 1296: # KEPT IN BOTH SEGMENTS AND CHECKED ON LOADING. ! 1297: # TO ASSIST WITH THIS CHECK, (XR) ON ENTRY IS A ! 1298: # POINTER TO AN SCBLK CONTAINING THE SPITBOL MAJOR ! 1299: # VERSION NUMBER V.V (SEE SYSID). ! 1300: # ! 1301: # 0 IF POSSIBLE, RETURN CONTROL TO JOB CONTROL ! 1302: # COMMAND LEVEL. THE EFFECT IF AVAILABLE WILL BE ! 1303: # SYSTEM DEPENDENT. ! 1304: # ! 1305: # +1, +2, +3 ! 1306: # CREATE IF POSSIBLE A LOAD MODULE FROM ALL OF ! 1307: # MEMORY. IT SHOULD BE POSSIBLE TO LOAD AND EXECUTE ! 1308: # THIS MODULE DIRECTLY. ! 1309: # ! 1310: # IN THE CASE OF SAVED LOAD MODULES, THE STATUS OF OPEN ! 1311: # FILES IS NOT PRESERVED AND IMPLEMENTORS MAY CHOOSE TO ! 1312: # OFFER MEANS OF ATTACHING FILES BEFORE EXECUTION OF LOAD ! 1313: # MODULES STARTS OR LEAVE IT TO THE USER TO INCLUDE ! 1314: # SUITABLE INPUT(), OUTPUT() CALLS IN HIS PROGRAM. ! 1315: # SYSXI SHOULD MAKE A NOTE THAT NO I/O CHANNELS, ! 1316: # INCLUDING STANDARD FILES, HAVE FILES ATTACHED SO THAT ! 1317: # CALLS OF SYSIN, SYSOU, SYSPR, SYSRD SHOULD FAIL UNLESS ! 1318: # NEW ASSOCIATIONS ARE MADE FOR THE LOAD MODULE. ! 1319: # AT LEAST IN THE CASE OF THE STANDARD OUTPUT FILE, IT IS ! 1320: # RECOMMENDED THAT EITHER THE USER BE REQUIRED TO ATTACH ! 1321: # A FILE OR THAT A DEFAULT FILE IS ATTACHED, SINCE THE ! 1322: # PROBLEM OF ERROR MESSAGES GENERATED BY THE LOAD MODULE ! 1323: # IS OTHERWISE SEVERE. AS A LAST RESORT, IF SPITBOL ! 1324: # ATTEMPTS TO WRITE TO THE STANDARD OUTPUT FILE AND GETS A ! 1325: # REPLY INDICATING THAT SUCH OUPUT IS UNACCEPTABLE IT STOPS ! 1326: # BY USING AN ENTRY TO SYSEJ WITH ENDING CODE 998. ! 1327: # AS DESCRIBED BELOW, PASSING OF SOME ARGUMENTS MAKES IT ! 1328: # CLEAR THAT LOAD MODULE WILL USE A STANDARD OUTPUT FILE. ! 1329: # ! 1330: # IF USE IS MADE OF FCBLKS FOR I/O ASSOCIATION, SPITBOL ! 1331: # BUILDS A CHAIN SO THAT THOSE IN USE MAY BE FOUND IN SYSXI ! 1332: # AND SYSEJ. THE NODES ARE 4 WORDS LONG. THIRD WORD ! 1333: # CONTAINS LINK TO NEXT NODE OR 0, FOURTH WORD CONTAINS ! 1334: # FCBLK POINTER. ! 1335: #page ! 1336: # ! 1337: # SYSXI (CONTINUED) ! 1338: # ! 1339: # (XL) ZERO OR SCBLK PTR ! 1340: # (XR) PTR TO V.V SCBLK ! 1341: # (IA) SIGNED INTEGER ARGUMENT ! 1342: # (WB) 0 OR PTR TO HEAD OF FCBLK CHAIN ! 1343: # JSR SYSXI CALL TO EXIT ! 1344: # PPM LOC REQUESTED ACTION NOT POSSIBLE ! 1345: # PPM LOC ACTION CAUSED IRRECOVERABLE ERROR ! 1346: # (REGISTERS) SHOULD BE PRESERVED OVER CALL ! 1347: # ! 1348: # LOADING AND RUNNING THE LOAD MODULE OR RETURNING FROM ! 1349: # JCL COMMAND LEVEL CAUSES EXECUTION TO RESUME AT THE POINT ! 1350: # AFTER THE ERROR RETURNS WHICH FOLLOW THE CALL OF SYSXI. ! 1351: # THE VALUE PASSED AS EXIT ARGUMENT IS USED TO INDICATE ! 1352: # OPTIONS REQUIRED ON RESUMPTION OF LOAD MODULE. ! 1353: # +1 OR -1 REQUIRE THAT ON RESUMPTION, SYSID AND SYSPP BE ! 1354: # CALLED AND A HEADING PRINTED ON THE STANDARD OUTPUT FILE. ! 1355: # +2 OR -2 INDICATE THAT SYSPP WILL BE CALLED BUT NOT SYSID ! 1356: # AND NO HEADING WILL BE PUT ON STANDARD OUTPUT FILE. ! 1357: # ABOVE OPTIONS HAVE THE OBVIOUS IMPLICATION THAT A ! 1358: # STANDARD O/P FILE MUST BE PROVIDED FOR THE LOAD MODULE. ! 1359: # +3 OR -3 INDICATE CALLS OF NEITHER SYSID NOR SYSPP ! 1360: # AND NO HEADING WILL BE PLACED ON STANDARD OUTPUT FILE. ! 1361: # NO RETURN FROM SYSXI IS POSSIBLE IF ANOTHER PROGRAM ! 1362: # IS LOADED AND ENTERED. ! 1363: #page ! 1364: # ! 1365: # INTRODUCE THE INTERNAL PROCEDURES. ! 1366: # ! 1367: .globl acess ! 1368: .globl acomp ! 1369: .globl alloc ! 1370: .globl alobf ! 1371: .globl alocs ! 1372: .globl alost ! 1373: .globl apndb ! 1374: .globl arith ! 1375: .globl asign ! 1376: .globl asinp ! 1377: .globl blkln ! 1378: .globl cdgcg ! 1379: .globl cdgex ! 1380: .globl cdgnm ! 1381: .globl cdgvl ! 1382: .globl cdwrd ! 1383: .globl cmgen ! 1384: .globl cmpil ! 1385: .globl cncrd ! 1386: .globl copyb ! 1387: .globl dffnc ! 1388: .globl dtach ! 1389: .globl dtype ! 1390: .globl dumpr ! 1391: .globl ermsg ! 1392: .globl ertex ! 1393: .globl evali ! 1394: .globl evalp ! 1395: .globl evals ! 1396: .globl evalx ! 1397: .globl exbld ! 1398: .globl expan ! 1399: .globl expap ! 1400: .globl expdm ! 1401: .globl expop ! 1402: .globl flstg ! 1403: .globl gbcol ! 1404: .globl gbcpf ! 1405: .globl gtarr ! 1406: #page ! 1407: .globl gtcod ! 1408: .globl gtexp ! 1409: .globl gtint ! 1410: .globl gtnum ! 1411: .globl gtnvr ! 1412: .globl gtpat ! 1413: .globl gtrea ! 1414: .globl gtsmi ! 1415: .globl gtstg ! 1416: .globl gtvar ! 1417: .globl hashs ! 1418: .globl icbld ! 1419: .globl ident ! 1420: .globl inout ! 1421: .globl insbf ! 1422: .globl iofcb ! 1423: .globl ioppf ! 1424: .globl ioput ! 1425: .globl ktrex ! 1426: .globl kwnam ! 1427: .globl lcomp ! 1428: .globl listr ! 1429: .globl listt ! 1430: .globl nexts ! 1431: .globl patin ! 1432: .globl patst ! 1433: .globl pbild ! 1434: .globl pconc ! 1435: .globl pcopy ! 1436: .globl prflr ! 1437: .globl prflu ! 1438: .globl prpar ! 1439: .globl prtch ! 1440: .globl prtic ! 1441: .globl prtis ! 1442: .globl prtin ! 1443: .globl prtmi ! 1444: .globl prtmx ! 1445: .globl prtnl ! 1446: .globl prtnm ! 1447: .globl prtnv ! 1448: .globl prtpg ! 1449: .globl prtps ! 1450: .globl prtsn ! 1451: .globl prtst ! 1452: #page ! 1453: .globl prttr ! 1454: .globl prtvl ! 1455: .globl prtvn ! 1456: .globl rcbld ! 1457: .globl readr ! 1458: .globl sbstr ! 1459: .globl scane ! 1460: .globl scngf ! 1461: .globl setvr ! 1462: .globl sorta ! 1463: .globl sortc ! 1464: .globl sortf ! 1465: .globl sorth ! 1466: .globl tfind ! 1467: .globl trace ! 1468: .globl trbld ! 1469: .globl trimr ! 1470: .globl trxeq ! 1471: .globl xscan ! 1472: .globl xscni ! 1473: # ! 1474: # INTRODUCE THE INTERNAL ROUTINES ! 1475: # ! 1476: .globl arref ! 1477: .globl cfunc ! 1478: .globl exfal ! 1479: .globl exint ! 1480: .globl exits ! 1481: .globl exixr ! 1482: .globl exnam ! 1483: .globl exnul ! 1484: .globl exrea ! 1485: .globl exsid ! 1486: .globl exvnm ! 1487: .globl failp ! 1488: .globl flpop ! 1489: .globl indir ! 1490: .globl match ! 1491: .globl retrn ! 1492: .globl stcov ! 1493: .globl stmgo ! 1494: .globl stopr ! 1495: .globl succp ! 1496: .globl sysab ! 1497: .globl systu ! 1498: #title s p i t b o l -- definitions and data structures ! 1499: #sec # start of definitions section ! 1500: # ! 1501: # DEFINITIONS OF MACHINE PARAMETERS ! 1502: # ! 1503: # THE MINIMAL TRANSLATOR SHOULD SUPPLY APPROPRIATE VALUES ! 1504: # FOR THE PARTICULAR TARGET MACHINE FOR ALL THE ! 1505: # EQU * ! 1506: # DEFINITIONS GIVEN AT THE START OF THIS SECTION. ! 1507: # ! 1508: .set cfp$a,256 # number of characters in alphabet ! 1509: # ! 1510: .set cfp$b,4 # bytes/word addressing factor ! 1511: # ! 1512: .set cfp$c,4 # number of characters per word ! 1513: # ! 1514: .set cfp$f,8 # offset in bytes to chars in ! 1515: # SCBLK. SEE SCBLK FORMAT. ! 1516: # ! 1517: .set cfp$i,1 # number of words in integer constant ! 1518: # ! 1519: .set cfp$m,0x7fffffff# max positive integer in one word ! 1520: # ! 1521: .set cfp$n,32 # number of bits in one word ! 1522: # ! 1523: # THE FOLLOWING DEFINITIONS REQUIRE THE SUPPLY OF EITHER ! 1524: # A SINGLE PARAMETER IF REAL ARITHMETIC IS OMITTED OR ! 1525: # THREE PARAMETERS IF REAL ARITHMETIC IS INCLUDED. ! 1526: # ! 1527: # ! 1528: .set cfp$r,1 # number of words in real constant ! 1529: # ! 1530: .set cfp$s,6 # number of sig digs for real output ! 1531: # ! 1532: .set cfp$x,2 # max digits in real exponent ! 1533: # ! 1534: .set mxdgs,cfp$s+cfp$x# max digits in real number ! 1535: # ! 1536: .set nstmx,mxdgs+5 # max space for real (for +0.e+) ! 1537: # ! 1538: # THE FOLLOWING DEFINITION FOR CFP$U SUPPLIES A REALISTIC ! 1539: # UPPER BOUND ON THE SIZE OF THE ALPHABET. CFP$U IS USED ! 1540: # TO SAVE SPACE IN THE SCANE BSW-IFF-ESW TABLE AND TO EASE ! 1541: # TRANSLATION STORAGE REQUIREMENTS. ! 1542: # ! 1543: .set cfp$u,128 # realistic upper bound on alphabet ! 1544: #page ! 1545: # ! 1546: # ENVIRONMENT PARAMETERS ! 1547: # ! 1548: # THE SPITBOL PROGRAM IS ESSENTIALLY INDEPENDENT OF ! 1549: # THE DEFINITIONS OF THESE PARAMETERS. HOWEVER, THE ! 1550: # EFFICIENCY OF THE SYSTEM MAY BE AFFECTED. CONSEQUENTLY, ! 1551: # THESE PARAMETERS MAY REQUIRE TUNING FOR A GIVEN VERSION ! 1552: # THE VALUES GIVEN IN COMMENTS HAVE BEEN SUCCESSFULLY USED. ! 1553: # ! 1554: # E$SRS IS THE NUMBER OF WORDS TO RESERVE AT THE END OF ! 1555: # STORAGE FOR END OF RUN PROCESSING. IT SHOULD BE ! 1556: # SET AS SMALL AS POSSIBLE WITHOUT CAUSING MEMORY OVERFLOW ! 1557: # IN CRITICAL SITUATIONS (E.G. MEMORY OVERFLOW TERMINATION) ! 1558: # AND SHOULD THUS RESERVE SUFFICIENT SPACE AT LEAST FOR ! 1559: # AN SCBLK CONTAINING SAY 30 CHARACTERS. ! 1560: # ! 1561: .set e$srs,50 # 30 words ! 1562: # ! 1563: # E$STS IS THE NUMBER OF WORDS GRABBED IN A CHUNK WHEN ! 1564: # STORAGE IS ALLOCATED IN THE STATIC REGION. THE MINIMUM ! 1565: # PERMITTED VALUE IS 256/CFP$B. LARGER VALUES WILL LEAD ! 1566: # TO INCREASED EFFICIENCY AT THE COST OF WASTING MEMORY. ! 1567: # ! 1568: .set e$sts,512 # 500 words ! 1569: # ! 1570: # E$CBS IS THE SIZE OF CODE BLOCK ALLOCATED INITIALLY AND ! 1571: # THE EXPANSION INCREMENT IF OVERFLOW OCCURS. IF THIS VALUE ! 1572: # IS TOO SMALL OR TOO LARGE, EXCESSIVE GARBAGE COLLECTIONS ! 1573: # WILL OCCUR DURING COMPILATION AND MEMORY MAY BE LOST ! 1574: # IN THE CASE OF A TOO LARGE VALUE. ! 1575: # ! 1576: .set e$cbs,512 # 500 words ! 1577: # ! 1578: # E$HNB IS THE NUMBER OF BUCKET HEADERS IN THE VARIABLE ! 1579: # HASH TABLE. IT SHOULD ALWAYS BE ODD. LARGER VALUES WILL ! 1580: # SPEED UP COMPILATION AND INDIRECT REFERENCES AT THE ! 1581: # EXPENSE OF ADDITIONAL STORAGE FOR THE HASH TABLE ITSELF. ! 1582: # ! 1583: .set e$hnb,253 # 127 bucket headers ! 1584: # ! 1585: # E$HNW IS THE MAXIMUM NUMBER OF WORDS OF A STRING ! 1586: # NAME WHICH PARTICIPATE IN THE STRING HASH ALGORITHM. ! 1587: # LARGER VALUES GIVE A BETTER HASH AT THE EXPENSE OF TAKING ! 1588: # LONGER TO COMPUTE THE HASH. THERE IS SOME OPTIMAL VALUE. ! 1589: # ! 1590: .set e$hnw,3 # 6 words ! 1591: # ! 1592: # E$FSP . IF THE AMOUNT OF FREE SPACE LEFT AFTER A GARBAGE ! 1593: # COLLECTION IS SMALL COMPARED TO THE TOTAL AMOUNT OF SPACE ! 1594: # IN USE GARBAGE COLLECTOR THRASHING IS LIKELY TO OCCUR AS ! 1595: # THIS SPACE IS USED UP. E$FSP IS A MEASURE OF THE ! 1596: # MINIMUM PERCENTAGE OF DYNAMIC MEMORY LEFT AS FREE SPACE ! 1597: # BEFORE THE SYSTEM ROUTINE SYSMM IS CALLED TO TRY TO ! 1598: # OBTAIN MORE MEMORY. ! 1599: # ! 1600: .set e$fsp,20 # 15 percent ! 1601: #page ! 1602: # ! 1603: # DEFINITIONS OF CODES FOR LETTERS ! 1604: # ! 1605: .set ch$la,65 # letter a ! 1606: .set ch$lb,66 # letter b ! 1607: .set ch$lc,67 # letter c ! 1608: .set ch$ld,68 # letter d ! 1609: .set ch$le,69 # letter e ! 1610: .set ch$lf,70 # letter f ! 1611: .set ch$lg,71 # letter g ! 1612: .set ch$lh,72 # letter h ! 1613: .set ch$li,73 # letter i ! 1614: .set ch$lj,74 # letter j ! 1615: .set ch$lk,75 # letter k ! 1616: .set ch$ll,76 # letter l ! 1617: .set ch$lm,77 # letter m ! 1618: .set ch$ln,78 # letter n ! 1619: .set ch$lo,79 # letter o ! 1620: .set ch$lp,80 # letter p ! 1621: .set ch$lq,81 # letter q ! 1622: .set ch$lr,82 # letter r ! 1623: .set ch$ls,83 # letter s ! 1624: .set ch$lt,84 # letter t ! 1625: .set ch$lu,85 # letter u ! 1626: .set ch$lv,86 # letter v ! 1627: .set ch$lw,87 # letter w ! 1628: .set ch$lx,88 # letter x ! 1629: .set ch$ly,89 # letter y ! 1630: .set ch$l$,90 # letter z ! 1631: # ! 1632: # DEFINITIONS OF CODES FOR DIGITS ! 1633: # ! 1634: .set ch$d0,48 # digit 0 ! 1635: .set ch$d1,49 # digit 1 ! 1636: .set ch$d2,50 # digit 2 ! 1637: .set ch$d3,51 # digit 3 ! 1638: .set ch$d4,52 # digit 4 ! 1639: .set ch$d5,53 # digit 5 ! 1640: .set ch$d6,54 # digit 6 ! 1641: .set ch$d7,55 # digit 7 ! 1642: .set ch$d8,56 # digit 8 ! 1643: .set ch$d9,57 # digit 9 ! 1644: #page ! 1645: # ! 1646: # DEFINITIONS OF CODES FOR SPECIAL CHARACTERS ! 1647: # ! 1648: # THE NAMES OF THESE CHARACTERS ARE RELATED TO THEIR ! 1649: # ORIGINAL REPRESENTATION IN THE EBCDIC SET CORRESPONDING ! 1650: # TO THE DESCRIPTION IN STANDARD SNOBOL4 MANUALS AND TEXTS. ! 1651: # ! 1652: .set ch$am,38 # keyword operator (ampersand) ! 1653: .set ch$as,42 # multiplication symbol (asterisk) ! 1654: .set ch$at,64 # cursor position operator (at) ! 1655: .set ch$bb,60 # left array bracket (less than) ! 1656: .set ch$bl,32 # blank ! 1657: .set ch$br,124 # alternation operator (vertical bar) ! 1658: .set ch$cl,58 # goto symbol (colon) ! 1659: .set ch$cm,44 # comma ! 1660: .set ch$dl,36 # indirection operator (dollar) ! 1661: .set ch$dt,46 # name operator (dot) ! 1662: .set ch$dq,34 # double quote ! 1663: .set ch$eq,61 # equal sign ! 1664: .set ch$ex,33 # exponentiation operator (exclm) ! 1665: .set ch$mn,45 # minus sign ! 1666: .set ch$nm,35 # number sign ! 1667: .set ch$nt,126 # negation operator (not) ! 1668: .set ch$pc,37 # percent ! 1669: .set ch$pl,43 # plus sign ! 1670: .set ch$pp,40 # left parenthesis ! 1671: .set ch$rb,62 # right array bracket (grtr than) ! 1672: .set ch$rp,41 # right parenthesis ! 1673: .set ch$qu,63 # interrogation operator (question) ! 1674: .set ch$sl,47 # slash ! 1675: .set ch$sm,59 # semicolon ! 1676: .set ch$sq,39 # single quote ! 1677: .set ch$un,95 # special identifier char (underline) ! 1678: .set ch$ob,91 # opening bracket ! 1679: .set ch$cb,93 # closing bracket ! 1680: #page ! 1681: # ! 1682: # REMAINING CHARS ARE OPTIONAL ADDITIONS TO THE STANDARDS. ! 1683: # ! 1684: # TAB CHARACTERS - SYNTACTICALLY EQUIVALENT TO BLANK ! 1685: # ! 1686: .set ch$ht,9 # horizontal tab ! 1687: # ! 1688: # LOWER CASE OR SHIFTED CASE ALPHABETIC CHARS ! 1689: # ! 1690: .set ch$$a,97 # shifted a ! 1691: .set ch$$b,98 # shifted b ! 1692: .set ch$$c,99 # shifted c ! 1693: .set ch$$d,100 # shifted d ! 1694: .set ch$$e,101 # shifted e ! 1695: .set ch$$f,102 # shifted f ! 1696: .set ch$$g,103 # shifted g ! 1697: .set ch$$h,104 # shifted h ! 1698: .set ch$$i,105 # shifted i ! 1699: .set ch$$j,106 # shifted j ! 1700: .set ch$$k,107 # shifted k ! 1701: .set ch$$l,108 # shifted l ! 1702: .set ch$$m,109 # shifted m ! 1703: .set ch$$n,110 # shifted n ! 1704: .set ch$$o,111 # shifted o ! 1705: .set ch$$p,112 # shifted p ! 1706: .set ch$$q,113 # shifted q ! 1707: .set ch$$r,114 # shifted r ! 1708: .set ch$$s,115 # shifted s ! 1709: .set ch$$t,116 # shifted t ! 1710: .set ch$$u,117 # shifted u ! 1711: .set ch$$v,118 # shifted v ! 1712: .set ch$$w,119 # shifted w ! 1713: .set ch$$x,120 # shifted x ! 1714: .set ch$$y,121 # shifted y ! 1715: .set ch$$$,122 # shifted z ! 1716: # IF A DELIMITER OTHER THAN CH$CM MUST BE USED IN ! 1717: # THE THIRD ARGUMENT OF INPUT(),OUTPUT() THEN .CIOD SHOULD ! 1718: # BE DEFINED AND A PARAMETER SUPPLIED FOR IODEL. ! 1719: # ! 1720: .set iodel,0 ! 1721: #page ! 1722: # ! 1723: # DATA BLOCK FORMATS AND DEFINITIONS ! 1724: # ! 1725: # THE FOLLOWING SECTIONS DESCRIBE THE DETAILED FORMAT OF ! 1726: # ALL POSSIBLE DATA BLOCKS IN STATIC AND DYNAMIC MEMORY. ! 1727: # ! 1728: # EVERY BLOCK HAS A NAME OF THE FORM XXBLK WHERE XX IS A ! 1729: # UNIQUE TWO CHARACTER IDENTIFIER. THE FIRST WORD OF EVERY ! 1730: # BLOCK MUST CONTAIN A POINTER TO A PROGRAM LOCATION IN THE ! 1731: # INTERPRETOR WHICH IS IMMEDIATELY PRECEDED BY AN ADDRESS ! 1732: # CONSTANT CONTAINING THE VALUE BL$XX WHERE XX IS THE BLOCK ! 1733: # IDENTIFIER. THIS PROVIDES A UNIFORM MECHANISM FOR ! 1734: # DISTINGUISHING BETWEEN THE VARIOUS BLOCK TYPES. ! 1735: # ! 1736: # IN SOME CASES, THE CONTENTS OF THE FIRST WORD IS CONSTANT ! 1737: # FOR A GIVEN BLOCK TYPE AND MERELY SERVES AS A POINTER ! 1738: # TO THE IDENTIFYING ADDRESS CONSTANT. HOWEVER, IN OTHER ! 1739: # CASES THERE ARE SEVERAL POSSIBILITIES FOR THE FIRST ! 1740: # WORD IN WHICH CASE EACH OF THE SEVERAL PROGRAM ENTRY ! 1741: # POINTS MUST BE PRECEDED BY THE APPROPRIATE CONSTANT. ! 1742: # ! 1743: # IN EACH BLOCK, SOME OF THE FIELDS ARE RELOCATABLE. THIS ! 1744: # MEANS THAT THEY MAY CONTAIN A POINTER TO ANOTHER BLOCK ! 1745: # IN THE DYNAMIC AREA. (TO BE MORE PRECISE, IF THEY CONTAIN ! 1746: # A POINTER WITHIN THE DYNAMIC AREA, THEN IT IS A POINTER ! 1747: # TO A BLOCK). SUCH FIELDS MUST BE MODIFIED BY THE GARBAGE ! 1748: # COLLECTOR (PROCEDURE GBCOL) WHENEVER BLOCKS ARE COMPACTED ! 1749: # IN THE DYNAMIC REGION. THE GARBAGE COLLECTOR (ACTUALLY ! 1750: # PROCEDURE GBCPF) REQUIRES THAT ALL SUCH RELOCATABLE ! 1751: # FIELDS IN A BLOCK MUST BE CONTIGUOUS. ! 1752: #page ! 1753: # ! 1754: # THE DESCRIPTION FORMAT USES THE FOLLOWING SCHEME. ! 1755: # ! 1756: # 1) BLOCK TITLE AND TWO CHARACTER IDENTIFIER ! 1757: # ! 1758: # 2) DESCRIPTION OF BASIC USE OF BLOCK AND INDICATION ! 1759: # OF CIRCUMSTANCES UNDER WHICH IT IS CONSTRUCTED. ! 1760: # ! 1761: # 3) PICTURE OF THE BLOCK FORMAT. IN THESE PICTURES LOW ! 1762: # MEMORY ADDRESSES ARE AT THE TOP OF THE PAGE. FIXED ! 1763: # LENGTH FIELDS ARE SURROUNDED BY I (LETTER I). FIELDS ! 1764: # WHICH ARE FIXED LENGTH BUT WHOSE LENGTH IS DEPENDENT ! 1765: # ON A CONFIGURATION PARAMETER ARE SURROUNDED BY * ! 1766: # (ASTERISK). VARIABLE LENGTH FIELDS ARE SURROUNDED ! 1767: # BY / (SLASH). ! 1768: # ! 1769: # 4) DEFINITION OF SYMBOLIC OFFSETS TO FIELDS IN ! 1770: # BLOCK AND OF THE SIZE OF THE BLOCK IF FIXED LENGTH ! 1771: # OR OF THE SIZE OF THE FIXED LENGTH FIELDS IF THE ! 1772: # BLOCK IS VARIABLE LENGTH. ! 1773: # NOTE THAT SOME ROUTINES SUCH AS GBCPF ASSUME ! 1774: # CERTAIN OFFSETS ARE EQUAL. THE DEFINITIONS ! 1775: # GIVEN HERE ENFORCE THIS. MAKE CHANGES TO ! 1776: # THEM ONLY WITH DUE CARE. ! 1777: # ! 1778: # DEFINITIONS OF COMMON OFFSETS ! 1779: # ! 1780: .set offs1,1 ! 1781: .set offs2,2 ! 1782: .set offs3,3 ! 1783: # ! 1784: # 5) DETAILED COMMENTS ON THE SIGNIFICANCE AND FORMATS ! 1785: # OF THE VARIOUS FIELDS. ! 1786: # ! 1787: # THE ORDER IS ALPHABETICAL BY IDENTIFICATION CODE. ! 1788: #page ! 1789: # ! 1790: # DEFINITIONS OF BLOCK CODES ! 1791: # ! 1792: # THIS TABLE PROVIDES A UNIQUE IDENTIFICATION CODE FOR ! 1793: # EACH SEPARATE BLOCK TYPE. THE FIRST WORD OF A BLOCK IN ! 1794: # THE DYNAMIC AREA ALWAYS CONTAINS THE ADDRESS OF A PROGRAM ! 1795: # ENTRY POINT. THE BLOCK CODE IS USED AS THE ENTRY POINT ID ! 1796: # THE ORDER OF THESE CODES DICTATES THE ORDER OF THE TABLE ! 1797: # USED BY THE DATATYPE FUNCTION (SCNMT IN THE CONSTANT SEC) ! 1798: # ! 1799: # BLOCK CODES FOR ACCESSIBLE DATATYPES ! 1800: # ! 1801: .set bl$ar,0 # arblk array ! 1802: .set bl$bc,bl$ar+1 # bcblk buffer ! 1803: .set bl$cd,bl$bc+1 # cdblk code ! 1804: .set bl$ex,bl$cd+1 # exblk expression ! 1805: .set bl$ic,bl$ex+1 # icblk integer ! 1806: .set bl$nm,bl$ic+1 # nmblk name ! 1807: .set bl$p0,bl$nm+1 # p0blk pattern ! 1808: .set bl$p1,bl$p0+1 # p1blk pattern ! 1809: .set bl$p2,bl$p1+1 # p2blk pattern ! 1810: .set bl$rc,bl$p2+1 # rcblk real ! 1811: .set bl$sc,bl$rc+1 # scblk string ! 1812: .set bl$se,bl$sc+1 # seblk expression ! 1813: .set bl$tb,bl$se+1 # tbblk table ! 1814: .set bl$vc,bl$tb+1 # vcblk array ! 1815: .set bl$xn,bl$vc+1 # xnblk external ! 1816: .set bl$xr,bl$xn+1 # xrblk external ! 1817: .set bl$pd,bl$xr+1 # pdblk program defined datatype ! 1818: # ! 1819: .set bl$$d,bl$pd+1 # number of block codes for data ! 1820: # ! 1821: # OTHER BLOCK CODES ! 1822: # ! 1823: .set bl$tr,bl$pd+1 # trblk ! 1824: .set bl$bf,bl$tr+1 # bfblk ! 1825: .set bl$cc,bl$bf+1 # ccblk ! 1826: .set bl$cm,bl$cc+1 # cmblk ! 1827: .set bl$ct,bl$cm+1 # ctblk ! 1828: .set bl$df,bl$ct+1 # dfblk ! 1829: .set bl$ef,bl$df+1 # efblk ! 1830: .set bl$ev,bl$ef+1 # evblk ! 1831: .set bl$ff,bl$ev+1 # ffblk ! 1832: .set bl$kv,bl$ff+1 # kvblk ! 1833: .set bl$pf,bl$kv+1 # pfblk ! 1834: .set bl$te,bl$pf+1 # teblk ! 1835: # ! 1836: .set bl$$i,0 # default identification code ! 1837: .set bl$$t,bl$tr+1 # code for data or trace block ! 1838: .set bl$$$,bl$te+1 # number of block codes ! 1839: #page ! 1840: # ! 1841: # FIELD REFERENCES ! 1842: # ! 1843: # REFERENCES TO THE FIELDS OF DATA BLOCKS ARE SYMBOLIC ! 1844: # (I.E. USE THE SYMBOLIC OFFSETS) WITH THE FOLLOWING ! 1845: # EXCEPTIONS. ! 1846: # ! 1847: # 1) REFERENCES TO THE FIRST WORD ARE USUALLY NOT ! 1848: # SYMBOLIC SINCE THEY USE THE (X) OPERAND FORMAT. ! 1849: # ! 1850: # 2) THE CODE WHICH CONSTRUCTS A BLOCK IS OFTEN NOT ! 1851: # SYMBOLIC AND SHOULD BE CHANGED IF THE CORRESPONDING ! 1852: # BLOCK FORMAT IS MODIFIED. ! 1853: # ! 1854: # 3) THE PLC AND PSC INSTRUCTIONS IMPLY AN OFFSET ! 1855: # CORRESPONDING TO THE DEFINITION OF CFP$F. ! 1856: # ! 1857: # 4) THERE ARE NON-SYMBOLIC REFERENCES (EASILY CHANGED) ! 1858: # IN THE GARBAGE COLLECTOR (PROCEDURES GBCPF, BLKLN). ! 1859: # ! 1860: # 5) THE FIELDS IDVAL, FARGS APPEAR IN SEVERAL BLOCKS ! 1861: # AND ANY CHANGES MUST BE MADE IN PARALLEL TO ALL ! 1862: # BLOCKS CONTAINING THE FIELDS. THE ACTUAL REFERENCES ! 1863: # TO THESE FIELDS ARE SYMBOLIC WITH THE ABOVE ! 1864: # LISTED EXCEPTIONS. ! 1865: # ! 1866: # 6) SEVERAL SPOTS IN THE CODE ASSUME THAT THE ! 1867: # DEFINITIONS OF THE FIELDS VRVAL, TEVAL, TRNXT ARE ! 1868: # THE SAME (THESE ARE SECTIONS OF CODE WHICH SEARCH ! 1869: # OUT ALONG A TRBLK CHAIN FROM A VARIABLE). ! 1870: # ! 1871: # 7) REFERENCES TO THE FIELDS OF AN ARRAY BLOCK IN THE ! 1872: # ARRAY REFERENCE ROUTINE ARREF ARE NON-SYMBOLIC. ! 1873: # ! 1874: # APART FROM THE EXCEPTIONS LISTED, REFERENCES ARE SYMBOLIC ! 1875: # AS FAR AS POSSIBLE AND MODIFYING THE ORDER OR NUMBER ! 1876: # OF FIELDS WILL NOT REQUIRE CHANGES. ! 1877: #page ! 1878: # ! 1879: # COMMON FIELDS FOR FUNCTION BLOCKS ! 1880: # ! 1881: # BLOCKS WHICH REPRESENT CALLABLE FUNCTIONS HAVE TWO ! 1882: # COMMON FIELDS AT THE START OF THE BLOCK AS FOLLOWS. ! 1883: # ! 1884: # +------------------------------------+ ! 1885: # I FCODE I ! 1886: # +------------------------------------+ ! 1887: # I FARGS I ! 1888: # +------------------------------------+ ! 1889: # / / ! 1890: # / REST OF FUNCTION BLOCK / ! 1891: # / / ! 1892: # +------------------------------------+ ! 1893: # ! 1894: .set fcode,0 # pointer to code for function ! 1895: .set fargs,1 # number of arguments ! 1896: # ! 1897: # FCODE IS A POINTER TO THE LOCATION IN THE INTERPRETOR ! 1898: # PROGRAM WHICH PROCESSES THIS TYPE OF FUNCTION CALL. ! 1899: # ! 1900: # FARGS IS THE EXPECTED NUMBER OF ARGUMENTS. THE ACTUAL ! 1901: # NUMBER OF ARGUMENTS IS ADJUSTED TO THIS AMOUNT BY ! 1902: # DELETING EXTRA ARGUMENTS OR SUPPLYING TRAILING NULLS ! 1903: # FOR MISSING ONES BEFORE TRANSFERRING THOUGH FCODE. ! 1904: # A VALUE OF 999 MAY BE USED IN THIS FIELD TO INDICATE A ! 1905: # VARIABLE NUMBER OF ARGUMENTS (SEE SVBLK FIELD SVNAR). ! 1906: # ! 1907: # THE BLOCK TYPES WHICH FOLLOW THIS SCHEME ARE. ! 1908: # ! 1909: # FFBLK FIELD FUNCTION ! 1910: # DFBLK DATATYPE FUNCTION ! 1911: # PFBLK PROGRAM DEFINED FUNCTION ! 1912: # EFBLK EXTERNAL LOADED FUNCTION ! 1913: #page ! 1914: # ! 1915: # IDENTIFICATION FIELD ! 1916: # ! 1917: # ! 1918: # ID FIELD ! 1919: # ! 1920: # CERTAIN PROGRAM ACCESSIBLE OBJECTS (THOSE WHICH CONTAIN ! 1921: # OTHER DATA VALUES AND CAN BE COPIED) ARE GIVEN A UNIQUE ! 1922: # IDENTIFICATION NUMBER (SEE EXSID). THIS ID VALUE IS AN ! 1923: # ADDRESS INTEGER VALUE WHICH IS ALWAYS STORED IN WORD TWO. ! 1924: # ! 1925: .set idval,1 # id value field ! 1926: # ! 1927: # THE BLOCKS CONTAINING AN IDVAL FIELD ARE. ! 1928: # ! 1929: # ARBLK ARRAY ! 1930: # BCBLK BUFFER CONTROL BLOCK ! 1931: # PDBLK PROGRAM DEFINED DATATYPE ! 1932: # TBBLK TABLE ! 1933: # VCBLK VECTOR BLOCK (ARRAY) ! 1934: # ! 1935: # NOTE THAT A ZERO IDVAL MEANS THAT THE BLOCK IS ONLY ! 1936: # HALF BUILT AND SHOULD NOT BE DUMPED (SEE DUMPR). ! 1937: #page ! 1938: # ! 1939: # ARRAY BLOCK (ARBLK) ! 1940: # ! 1941: # AN ARRAY BLOCK REPRESENTS AN ARRAY VALUE OTHER THAN ONE ! 1942: # WITH ONE DIMENSION WHOSE LOWER BOUND IS ONE (SEE VCBLK). ! 1943: # AN ARBLK IS BUILT WITH A CALL TO THE FUNCTIONS CONVERT ! 1944: # (S$CNV) OR ARRAY (S$ARR). ! 1945: # ! 1946: # +------------------------------------+ ! 1947: # I ARTYP I ! 1948: # +------------------------------------+ ! 1949: # I IDVAL I ! 1950: # +------------------------------------+ ! 1951: # I ARLEN I ! 1952: # +------------------------------------+ ! 1953: # I AROFS I ! 1954: # +------------------------------------+ ! 1955: # I ARNDM I ! 1956: # +------------------------------------+ ! 1957: # * ARLBD * ! 1958: # +------------------------------------+ ! 1959: # * ARDIM * ! 1960: # +------------------------------------+ ! 1961: # * * ! 1962: # * ABOVE 2 FLDS REPEATED FOR EACH DIM * ! 1963: # * * ! 1964: # +------------------------------------+ ! 1965: # I ARPRO I ! 1966: # +------------------------------------+ ! 1967: # / / ! 1968: # / ARVLS / ! 1969: # / / ! 1970: # +------------------------------------+ ! 1971: #page ! 1972: # ! 1973: # ARRAY BLOCK (CONTINUED) ! 1974: # ! 1975: .set artyp,0 # pointer to dummy routine b$art ! 1976: .set arlen,idval+1 # length of arblk in bytes ! 1977: .set arofs,arlen+1 # offset in arblk to arpro field ! 1978: .set arndm,arofs+1 # number of dimensions ! 1979: .set arlbd,arndm+1 # low bound (first subscript) ! 1980: .set ardim,arlbd+cfp$i# dimension (first subscript) ! 1981: .set arlb2,ardim+cfp$i# low bound (second subscript) ! 1982: .set ardm2,arlb2+cfp$i# dimension (second subscript) ! 1983: .set arpro,ardim+cfp$i# array prototype (one dimension) ! 1984: .set arvls,arpro+1 # start of values (one dimension) ! 1985: .set arpr2,ardm2+cfp$i# array prototype (two dimensions) ! 1986: .set arvl2,arpr2+1 # start of values (two dimensions) ! 1987: .set arsi$,arlbd # number of standard fields in block ! 1988: .set ardms,arlb2-arlbd# size of info for one set of bounds ! 1989: # ! 1990: # THE BOUNDS AND DIMENSION FIELDS ARE SIGNED INTEGER ! 1991: # VALUES AND EACH OCCUPY CFP$I WORDS IN THE ARBLK. ! 1992: # ! 1993: # THE LENGTH OF AN ARBLK IN BYTES MAY NOT EXCEED MXLEN. ! 1994: # THIS IS REQUIRED TO KEEP NAME OFFSETS GARBAGE COLLECTABLE ! 1995: # ! 1996: # THE ACTUAL VALUES ARE ARRANGED IN ROW-WISE ORDER AND ! 1997: # CAN CONTAIN A DATA POINTER OR A POINTER TO A TRBLK. ! 1998: # ! 1999: # BUFFER CONTROL BLOCK (BCBLK) ! 2000: # ! 2001: # A BCBLK IS BUILT FOR EVERY BFBLK. ! 2002: # ! 2003: # +------------------------------------+ ! 2004: # I BCTYP I ! 2005: # +------------------------------------+ ! 2006: # I IDVAL I ! 2007: # +------------------------------------+ ! 2008: # I BCLEN I ! 2009: # +------------------------------------+ ! 2010: # I BCBUF I ! 2011: # +------------------------------------+ ! 2012: # ! 2013: .set bctyp,0 # ptr to dummy routine b$bct ! 2014: .set bclen,idval+1 # defined buffer length ! 2015: .set bcbuf,bclen+1 # ptr to bfblk ! 2016: .set bcsi$,bcbuf+1 # size of bcblk ! 2017: # ! 2018: # A BCBLK IS AN INDIRECT CONTROL HEADER FOR BFBLK. ! 2019: # THE REASON FOR NOT STORING THIS DATA DIRECTLY ! 2020: # IN THE RELATED BFBLK IS SO THAT THE BFBLK CAN ! 2021: # MAINTAIN THE SAME SKELETAL STRUCTURE AS AN SCBLK ! 2022: # THUS FACILITATING TRANSPARENT STRING OPERATIONS ! 2023: # (FOR THE MOST PART). SPECIFICALLY, CFP$F IS THE ! 2024: # SAME FOR A BFBLK AS FOR AN SCBLK. BY CONVENTION, ! 2025: # WHEREEVER A BUFFER VALUE IS EMPLOYED, THE BCBLK ! 2026: # IS POINTED TO. ! 2027: # ! 2028: # THE CORRESPONDING BFBLK IS POINTED TO BY THE ! 2029: # BCBUF POINTER IN THE BCBLK. ! 2030: # ! 2031: # BCLEN IS THE CURRENT DEFINED SIZE OF THE CHARACTER ! 2032: # ARRAY IN THE BFBLK. CHARACTERS FOLLOWING THE OFFSET ! 2033: # OF BCLEN ARE UNDEFINED. ! 2034: # ! 2035: #page ! 2036: # ! 2037: # STRING BUFFER BLOCK (BFBLK) ! 2038: # ! 2039: # A BFBLK IS BUILT BY A CALL TO BUFFER(...) ! 2040: # ! 2041: # +------------------------------------+ ! 2042: # I BFTYP I ! 2043: # +------------------------------------+ ! 2044: # I BFALC I ! 2045: # +------------------------------------+ ! 2046: # / / ! 2047: # / BFCHR / ! 2048: # / / ! 2049: # +------------------------------------+ ! 2050: # ! 2051: .set bftyp,0 # ptr to dummy routine b$bft ! 2052: .set bfalc,bftyp+1 # allocated size of buffer ! 2053: .set bfchr,bfalc+1 # characters of string ! 2054: .set bfsi$,bfchr # size of standard fields in bfblk ! 2055: # ! 2056: # THE CHARACTERS IN THE BUFFER ARE STORED LEFT JUSTIFIED. ! 2057: # THE FINAL WORD OF DEFINED CHARACTERS IS ALWAYS ZERO ! 2058: # (CHARACTER) PADDED. ANY TRAILING ALLOCATION PAST THE ! 2059: # WORD CONTAINING THE LAST CHARACTER CONTAINS ! 2060: # UNPREDICTABLE CONTENTS AND IS NEVER REFERENCED. ! 2061: # ! 2062: # NOTE THAT THE OFFSET TO THE CHARACTERS OF THE STRING ! 2063: # IS GIVEN BY CFP$F, AS WITH AN SCBLK. HOWEVER, THE ! 2064: # OFFSET WHICH IS OCCUPIED BY THE LENGTH FOR AN SCBLK ! 2065: # IS THE TOTAL CHAR SPACE FOR BFBLKS, AND ROUTINES WHICH ! 2066: # DEAL WITH BOTH MUST ACCOUNT FOR THIS DIFFERENCE. ! 2067: # ! 2068: # THE VALUE OF BFALC MAY NOT EXCEED MXLEN. THE VALUE OF ! 2069: # BCLEN IS ALWAYS LESS THAN OR EQUAL TO BFALC. ! 2070: # ! 2071: #page ! 2072: # ! 2073: # CODE CONSTRUCTION BLOCK (CCBLK) ! 2074: # ! 2075: # AT ANY ONE MOMENT THERE IS AT MOST ONE CCBLK INTO ! 2076: # WHICH THE COMPILER IS CURRENTLY STORING CODE (CDWRD). ! 2077: # ! 2078: # +------------------------------------+ ! 2079: # I CCTYP I ! 2080: # +------------------------------------+ ! 2081: # I CCLEN I ! 2082: # +------------------------------------+ ! 2083: # I CCUSE I ! 2084: # +------------------------------------+ ! 2085: # / / ! 2086: # / CCCOD / ! 2087: # / / ! 2088: # +------------------------------------+ ! 2089: # ! 2090: .set cctyp,0 # pointer to dummy routine b$cct ! 2091: .set cclen,cctyp+1 # length of ccblk in bytes ! 2092: .set ccuse,cclen+1 # offset past last used word (bytes) ! 2093: .set cccod,ccuse+1 # start of generated code in block ! 2094: # ! 2095: # THE REASON THAT THE CCBLK IS A SEPARATE BLOCK TYPE FROM ! 2096: # THE USUAL CDBLK IS THAT THE GARBAGE COLLECTOR MUST ! 2097: # ONLY PROCESS THOSE FIELDS WHICH HAVE BEEN SET (SEE GBCPF) ! 2098: #page ! 2099: # ! 2100: # CODE BLOCK (CDBLK) ! 2101: # ! 2102: # A CODE BLOCK IS BUILT FOR EACH STATEMENT COMPILED DURING ! 2103: # THE INITIAL COMPILATION OR BY SUBSEQUENT CALLS TO CODE. ! 2104: # ! 2105: # +------------------------------------+ ! 2106: # I CDJMP I ! 2107: # +------------------------------------+ ! 2108: # I CDSTM I ! 2109: # +------------------------------------+ ! 2110: # I CDLEN I ! 2111: # +------------------------------------+ ! 2112: # I CDFAL I ! 2113: # +------------------------------------+ ! 2114: # / / ! 2115: # / CDCOD / ! 2116: # / / ! 2117: # +------------------------------------+ ! 2118: # ! 2119: .set cdjmp,0 # ptr to routine to execute statement ! 2120: .set cdstm,cdjmp+1 # statement number ! 2121: .set cdlen,offs2 # length of cdblk in bytes ! 2122: .set cdfal,offs3 # failure exit (see below) ! 2123: .set cdcod,cdfal+1 # executable pseudo-code ! 2124: .set cdsi$,cdcod # number of standard fields in cdblk ! 2125: # ! 2126: # CDSTM IS THE STATEMENT NUMBER OF THE CURRENT STATEMENT. ! 2127: # ! 2128: # CDJMP, CDFAL ARE SET AS FOLLOWS. ! 2129: # ! 2130: # 1) IF THE FAILURE EXIT IS THE NEXT STATEMENT ! 2131: # ! 2132: # CDJMP = B$CDS ! 2133: # CDFAL = PTR TO CDBLK FOR NEXT STATEMENT ! 2134: # ! 2135: # 2) IF THE FAILURE EXIT IS A SIMPLE LABEL NAME ! 2136: # ! 2137: # CDJMP = B$CDS ! 2138: # CDFAL IS A PTR TO THE VRTRA FIELD OF THE VRBLK ! 2139: # ! 2140: # 3) IF THERE IS NO FAILURE EXIT (-NOFAIL MODE) ! 2141: # ! 2142: # CDJMP = B$CDS ! 2143: # CDFAL = O$UNF ! 2144: # ! 2145: # 4) IF THE FAILURE EXIT IS COMPLEX OR DIRECT ! 2146: # ! 2147: # CDJMP = B$CDC ! 2148: # CDFAL IS THE OFFSET TO THE O$GOF WORD ! 2149: #page ! 2150: # ! 2151: # CODE BLOCK (CONTINUED) ! 2152: # ! 2153: # CDCOD IS THE START OF THE ACTUAL CODE. FIRST WE DESCRIBE ! 2154: # THE CODE GENERATED FOR AN EXPRESSION. IN AN EXPRESSION, ! 2155: # ELEMENTS ARE FETCHED BY NAME OR BY VALUE. FOR EXAMPLE, ! 2156: # THE BINARY EQUAL OPERATOR FETCHES ITS LEFT ARGUMENT ! 2157: # BY NAME AND ITS RIGHT ARGUMENT BY VALUE. THESE TWO ! 2158: # CASES GENERATE QUITE DIFFERENT CODE AND ARE DESCRIBED ! 2159: # SEPARATELY. FIRST WE CONSIDER THE CODE BY VALUE CASE. ! 2160: # ! 2161: # GENERATION OF CODE BY VALUE FOR EXPRESSIONS ELEMENTS. ! 2162: # ! 2163: # EXPRESSION POINTER TO EXBLK OR SEBLK ! 2164: # ! 2165: # INTEGER CONSTANT POINTER TO ICBLK ! 2166: # ! 2167: # NULL CONSTANT POINTER TO NULLS ! 2168: # ! 2169: # PATTERN (RESULTING FROM PREEVALUATION) ! 2170: # =O$LPT ! 2171: # POINTER TO P0BLK,P1BLK OR P2BLK ! 2172: # ! 2173: # REAL CONSTANT POINTER TO RCBLK ! 2174: # ! 2175: # STRING CONSTANT POINTER TO SCBLK ! 2176: # ! 2177: # VARIABLE POINTER TO VRGET FIELD OF VRBLK ! 2178: # ! 2179: # ADDITION VALUE CODE FOR LEFT OPERAND ! 2180: # VALUE CODE FOR RIGHT OPERAND ! 2181: # =O$ADD ! 2182: # ! 2183: # AFFIRMATION VALUE CODE FOR OPERAND ! 2184: # =O$AFF ! 2185: # ! 2186: # ALTERNATION VALUE CODE FOR LEFT OPERAND ! 2187: # VALUE CODE FOR RIGHT OPERAND ! 2188: # =O$ALT ! 2189: # ! 2190: # ARRAY REFERENCE (CASE OF ONE SUBSCRIPT) ! 2191: # VALUE CODE FOR ARRAY OPERAND ! 2192: # VALUE CODE FOR SUBSCRIPT OPERAND ! 2193: # =O$AOV ! 2194: # ! 2195: # (CASE OF MORE THAN ONE SUBSCRIPT) ! 2196: # VALUE CODE FOR ARRAY OPERAND ! 2197: # VALUE CODE FOR FIRST SUBSCRIPT ! 2198: # VALUE CODE FOR SECOND SUBSCRIPT ! 2199: # ... ! 2200: # VALUE CODE FOR LAST SUBSCRIPT ! 2201: # =O$AMV ! 2202: # NUMBER OF SUBSCRIPTS ! 2203: #page ! 2204: # ! 2205: # CODE BLOCK (CONTINUED) ! 2206: # ! 2207: # ASSIGNMENT (TO NATURAL VARIABLE) ! 2208: # VALUE CODE FOR RIGHT OPERAND ! 2209: # POINTER TO VRSTO FIELD OF VRBLK ! 2210: # ! 2211: # (TO ANY OTHER VARIABLE) ! 2212: # NAME CODE FOR LEFT OPERAND ! 2213: # VALUE CODE FOR RIGHT OPERAND ! 2214: # =O$ASS ! 2215: # ! 2216: # COMPILE ERROR =O$CER ! 2217: # ! 2218: # ! 2219: # COMPLEMENTATION VALUE CODE FOR OPERAND ! 2220: # =O$COM ! 2221: # ! 2222: # CONCATENATION (CASE OF PRED FUNC LEFT OPERAND) ! 2223: # VALUE CODE FOR LEFT OPERAND ! 2224: # =O$POP ! 2225: # VALUE CODE FOR RIGHT OPERAND ! 2226: # ! 2227: # (ALL OTHER CASES) ! 2228: # VALUE CODE FOR LEFT OPERAND ! 2229: # VALUE CODE FOR RIGHT OPERAND ! 2230: # =O$CNC ! 2231: # ! 2232: # CURSOR ASSIGNMENT NAME CODE FOR OPERAND ! 2233: # =O$CAS ! 2234: # ! 2235: # DIVISION VALUE CODE FOR LEFT OPERAND ! 2236: # VALUE CODE FOR RIGHT OPERAND ! 2237: # =O$DVD ! 2238: # ! 2239: # EXPONENTIATION VALUE CODE FOR LEFT OPERAND ! 2240: # VALUE CODE FOR RIGHT OPERAND ! 2241: # =O$EXP ! 2242: # ! 2243: # FUNCTION CALL (CASE OF CALL TO SYSTEM FUNCTION) ! 2244: # VALUE CODE FOR FIRST ARGUMENT ! 2245: # VALUE CODE FOR SECOND ARGUMENT ! 2246: # ... ! 2247: # VALUE CODE FOR LAST ARGUMENT ! 2248: # POINTER TO SVFNC FIELD OF SVBLK ! 2249: # ! 2250: #page ! 2251: # ! 2252: # CODE BLOCK (CONTINUED) ! 2253: # ! 2254: # FUNCTION CALL (CASE OF NON-SYSTEM FUNCTION 1 ARG) ! 2255: # VALUE CODE FOR ARGUMENT ! 2256: # =O$FNS ! 2257: # POINTER TO VRBLK FOR FUNCTION ! 2258: # ! 2259: # (NON-SYSTEM FUNCTION, GT 1 ARG) ! 2260: # VALUE CODE FOR FIRST ARGUMENT ! 2261: # VALUE CODE FOR SECOND ARGUMENT ! 2262: # ... ! 2263: # VALUE CODE FOR LAST ARGUMENT ! 2264: # =O$FNC ! 2265: # NUMBER OF ARGUMENTS ! 2266: # POINTER TO VRBLK FOR FUNCTION ! 2267: # ! 2268: # IMMEDIATE ASSIGNMENT VALUE CODE FOR LEFT OPERAND ! 2269: # NAME CODE FOR RIGHT OPERAND ! 2270: # =O$IMA ! 2271: # ! 2272: # INDIRECTION VALUE CODE FOR OPERAND ! 2273: # =O$INV ! 2274: # ! 2275: # INTERROGATION VALUE CODE FOR OPERAND ! 2276: # =O$INT ! 2277: # ! 2278: # KEYWORD REFERENCE NAME CODE FOR OPERAND ! 2279: # =O$KWV ! 2280: # ! 2281: # MULTIPLICATION VALUE CODE FOR LEFT OPERAND ! 2282: # VALUE CODE FOR RIGHT OPERAND ! 2283: # =O$MLT ! 2284: # ! 2285: # NAME REFERENCE (NATURAL VARIABLE CASE) ! 2286: # POINTER TO NMBLK FOR NAME ! 2287: # ! 2288: # (ALL OTHER CASES) ! 2289: # NAME CODE FOR OPERAND ! 2290: # =O$NAM ! 2291: # ! 2292: # NEGATION =O$NTA ! 2293: # CDBLK OFFSET OF O$NTC WORD ! 2294: # VALUE CODE FOR OPERAND ! 2295: # =O$NTB ! 2296: # =O$NTC ! 2297: #page ! 2298: # ! 2299: # CODE BLOCK (CONTINUED) ! 2300: # ! 2301: # PATTERN ASSIGNMENT VALUE CODE FOR LEFT OPERAND ! 2302: # NAME CODE FOR RIGHT OPERAND ! 2303: # =O$PAS ! 2304: # ! 2305: # PATTERN MATCH VALUE CODE FOR LEFT OPERAND ! 2306: # VALUE CODE FOR RIGHT OPERAND ! 2307: # =O$PMV ! 2308: # ! 2309: # PATTERN REPLACEMENT NAME CODE FOR SUBJECT ! 2310: # VALUE CODE FOR PATTERN ! 2311: # =O$PMN ! 2312: # VALUE CODE FOR REPLACEMENT ! 2313: # =O$RPL ! 2314: # ! 2315: # SELECTION (FOR FIRST ALTERNATIVE) ! 2316: # =O$SLA ! 2317: # CDBLK OFFSET TO NEXT O$SLC WORD ! 2318: # VALUE CODE FOR FIRST ALTERNATIVE ! 2319: # =O$SLB ! 2320: # CDBLK OFFSET PAST ALTERNATIVES ! 2321: # ! 2322: # (FOR SUBSEQUENT ALTERNATIVES) ! 2323: # =O$SLC ! 2324: # CDBLK OFFSET TO NEXT O$SLC,O$SLD ! 2325: # VALUE CODE FOR ALTERNATIVE ! 2326: # =O$SLB ! 2327: # OFFSET IN CDBLK PAST ALTERNATIVES ! 2328: # ! 2329: # (FOR LAST ALTERNATIVE) ! 2330: # =O$SLD ! 2331: # VALUE CODE FOR LAST ALTERNATIVE ! 2332: # ! 2333: # SUBTRACTION VALUE CODE FOR LEFT OPERAND ! 2334: # VALUE CODE FOR RIGHT OPERAND ! 2335: # =O$SUB ! 2336: #page ! 2337: # ! 2338: # CODE BLOCK (CONTINUED) ! 2339: # ! 2340: # GENERATION OF CODE BY NAME FOR EXPRESSION ELEMENTS. ! 2341: # ! 2342: # VARIABLE =O$LVN ! 2343: # POINTER TO VRBLK ! 2344: # ! 2345: # EXPRESSION (CASE OF *NATURAL VARIABLE) ! 2346: # =O$LVN ! 2347: # POINTER TO VRBLK ! 2348: # ! 2349: # (ALL OTHER CASES) ! 2350: # =O$LEX ! 2351: # POINTER TO EXBLK ! 2352: # ! 2353: # ! 2354: # ARRAY REFERENCE (CASE OF ONE SUBSCRIPT) ! 2355: # VALUE CODE FOR ARRAY OPERAND ! 2356: # VALUE CODE FOR SUBSCRIPT OPERAND ! 2357: # =O$AON ! 2358: # ! 2359: # (CASE OF MORE THAN ONE SUBSCRIPT) ! 2360: # VALUE CODE FOR ARRAY OPERAND ! 2361: # VALUE CODE FOR FIRST SUBSCRIPT ! 2362: # VALUE CODE FOR SECOND SUBSCRIPT ! 2363: # ... ! 2364: # VALUE CODE FOR LAST SUBSCRIPT ! 2365: # =O$AMN ! 2366: # NUMBER OF SUBSCRIPTS ! 2367: # ! 2368: # COMPILE ERROR =O$CER ! 2369: # ! 2370: # FUNCTION CALL (SAME CODE AS FOR VALUE CALL) ! 2371: # =O$FNE ! 2372: # ! 2373: # INDIRECTION VALUE CODE FOR OPERAND ! 2374: # =O$INN ! 2375: # ! 2376: # KEYWORD REFERENCE NAME CODE FOR OPERAND ! 2377: # =O$KWN ! 2378: # ! 2379: # ANY OTHER OPERAND IS AN ERROR IN A NAME POSITION ! 2380: # ! 2381: # NOTE THAT IN THIS DESCRIPTION, =O$XXX REFERS TO THE ! 2382: # GENERATION OF A WORD CONTAINING THE ADDRESS OF ANOTHER ! 2383: # WORD WHICH CONTAINS THE ENTRY POINT ADDRESS O$XXX. ! 2384: #page ! 2385: # ! 2386: # CODE BLOCK (CONTINUED) ! 2387: # ! 2388: # NOW WE CONSIDER THE OVERALL STRUCTURE OF THE CODE BLOCK ! 2389: # FOR A STATEMENT WITH POSSIBLE GOTO FIELDS. ! 2390: # ! 2391: # FIRST COMES THE CODE FOR THE STATEMENT BODY. ! 2392: # THE STATEMENT BODY IS AN EXPRESSION TO BE EVALUATED ! 2393: # BY VALUE ALTHOUGH THE VALUE IS NOT ACTUALLY REQUIRED. ! 2394: # NORMAL VALUE CODE IS GENERATED FOR THE BODY OF THE ! 2395: # STATEMENT EXCEPT IN THE CASE OF A PATTERN MATCH BY ! 2396: # VALUE, IN WHICH CASE THE FOLLOWING IS GENERATED. ! 2397: # ! 2398: # VALUE CODE FOR LEFT OPERAND ! 2399: # VALUE CODE FOR RIGHT OPERAND ! 2400: # =O$PMS ! 2401: # ! 2402: # NEXT WE HAVE THE CODE FOR THE SUCCESS GOTO. THERE ARE ! 2403: # SEVERAL CASES AS FOLLOWS. ! 2404: # ! 2405: # 1) NO SUCCESS GOTO PTR TO CDBLK FOR NEXT STATEMENT ! 2406: # ! 2407: # 2) SIMPLE LABEL PTR TO VRTRA FIELD OF VRBLK ! 2408: # ! 2409: # 3) COMPLEX GOTO (CODE BY NAME FOR GOTO OPERAND) ! 2410: # =O$GOC ! 2411: # ! 2412: # 4) DIRECT GOTO (CODE BY VALUE FOR GOTO OPERAND) ! 2413: # =O$GOD ! 2414: # ! 2415: # FOLLOWING THIS WE GENERATE CODE FOR THE FAILURE GOTO IF ! 2416: # IT IS DIRECT OR IF IT IS COMPLEX, SIMPLE FAILURE GOTOS ! 2417: # HAVING BEEN HANDLED BY AN APPROPRIATE SETTING OF THE ! 2418: # CDFAL FIELD OF THE CDBLK. THE GENERATED CODE IS ONE ! 2419: # OF THE FOLLOWING. ! 2420: # ! 2421: # 1) COMPLEX FGOTO =O$FIF ! 2422: # =O$GOF ! 2423: # NAME CODE FOR GOTO OPERAND ! 2424: # =O$GOC ! 2425: # ! 2426: # 2) DIRECT FGOTO =O$FIF ! 2427: # =O$GOF ! 2428: # VALUE CODE FOR GOTO OPERAND ! 2429: # =O$GOD ! 2430: # ! 2431: # AN OPTIMIZATION OCCURS IF THE SUCCESS AND FAILURE GOTOS ! 2432: # ARE IDENTICAL AND EITHER COMPLEX OR DIRECT. IN THIS CASE, ! 2433: # NO CODE IS GENERATED FOR THE SUCCESS GOTO AND CONTROL ! 2434: # IS ALLOWED TO FALL INTO THE FAILURE GOTO ON SUCCESS. ! 2435: #page ! 2436: # ! 2437: # COMPILER BLOCK (CMBLK) ! 2438: # ! 2439: # A COMPILER BLOCK (CMBLK) IS BUILT BY EXPAN TO REPRESENT ! 2440: # ONE NODE OF A TREE STRUCTURED EXPRESSION REPRESENTATION. ! 2441: # ! 2442: # +------------------------------------+ ! 2443: # I CMIDN I ! 2444: # +------------------------------------+ ! 2445: # I CMLEN I ! 2446: # +------------------------------------+ ! 2447: # I CMTYP I ! 2448: # +------------------------------------+ ! 2449: # I CMOPN I ! 2450: # +------------------------------------+ ! 2451: # / CMVLS OR CMROP / ! 2452: # / / ! 2453: # / CMLOP / ! 2454: # / / ! 2455: # +------------------------------------+ ! 2456: # ! 2457: .set cmidn,0 # pointer to dummy routine b$cmt ! 2458: .set cmlen,cmidn+1 # length of cmblk in bytes ! 2459: .set cmtyp,cmlen+1 # type (c$xxx, see list below) ! 2460: .set cmopn,cmtyp+1 # operand pointer (see below) ! 2461: .set cmvls,cmopn+1 # operand value pointers (see below) ! 2462: .set cmrop,cmvls # right (only) operator operand ! 2463: .set cmlop,cmvls+1 # left operator operand ! 2464: .set cmsi$,cmvls # number of standard fields in cmblk ! 2465: .set cmus$,cmsi$+1 # size of unary operator cmblk ! 2466: .set cmbs$,cmsi$+2 # size of binary operator cmblk ! 2467: .set cmar1,cmvls+1 # array subscript pointers ! 2468: # ! 2469: # THE CMOPN AND CMVLS FIELDS ARE SET AS FOLLOWS ! 2470: # ! 2471: # ARRAY REFERENCE CMOPN = PTR TO ARRAY OPERAND ! 2472: # CMVLS = PTRS TO SUBSCRIPT OPERANDS ! 2473: # ! 2474: # FUNCTION CALL CMOPN = PTR TO VRBLK FOR FUNCTION ! 2475: # CMVLS = PTRS TO ARGUMENT OPERANDS ! 2476: # ! 2477: # SELECTION CMOPN = ZERO ! 2478: # CMVLS = PTRS TO ALTERNATE OPERANDS ! 2479: # ! 2480: # UNARY OPERATOR CMOPN = PTR TO OPERATOR DVBLK ! 2481: # CMROP = PTR TO OPERAND ! 2482: # ! 2483: # BINARY OPERATOR CMOPN = PTR TO OPERATOR DVBLK ! 2484: # CMROP = PTR TO RIGHT OPERAND ! 2485: # CMLOP = PTR TO LEFT OPERAND ! 2486: #page ! 2487: # ! 2488: # CMTYP IS SET TO INDICATE THE TYPE OF EXPRESSION ELEMENT ! 2489: # AS SHOWN BY THE FOLLOWING TABLE OF DEFINITIONS. ! 2490: # ! 2491: .set c$arr,0 # array reference ! 2492: .set c$fnc,c$arr+1 # function call ! 2493: .set c$def,c$fnc+1 # deferred expression (unary *) ! 2494: .set c$ind,c$def+1 # indirection (unary $) ! 2495: .set c$key,c$ind+1 # keyword reference (unary ampersand) ! 2496: .set c$ubo,c$key+1 # undefined binary operator ! 2497: .set c$uuo,c$ubo+1 # undefined unary operator ! 2498: .set c$uo$,c$uuo+1 # test value (=c$uuo+1=c$ubo+2) ! 2499: .set c$$nm,c$uuo+1 # number of codes for name operands ! 2500: # ! 2501: # THE REMAINING TYPES INDICATE EXPRESSION ELEMENTS WHICH ! 2502: # CAN ONLY BE EVALUATED BY VALUE (NOT BY NAME). ! 2503: # ! 2504: .set c$bvl,c$uuo+1 # binary op with value operands ! 2505: .set c$uvl,c$bvl+1 # unary operator with value operand ! 2506: .set c$alt,c$uvl+1 # alternation (binary bar) ! 2507: .set c$cnc,c$alt+1 # concatenation ! 2508: .set c$cnp,c$cnc+1 # concatenation, not pattern match ! 2509: .set c$unm,c$cnp+1 # unary op with name operand ! 2510: .set c$bvn,c$unm+1 # binary op (operands by value, name) ! 2511: .set c$ass,c$bvn+1 # assignment ! 2512: .set c$int,c$ass+1 # interrogation ! 2513: .set c$neg,c$int+1 # negation (unary not) ! 2514: .set c$sel,c$neg+1 # selection ! 2515: .set c$pmt,c$sel+1 # pattern match ! 2516: # ! 2517: .set c$pr$,c$bvn # last preevaluable code ! 2518: .set c$$nv,c$pmt+1 # number of different cmblk types ! 2519: #page ! 2520: # ! 2521: # CHARACTER TABLE BLOCK (CTBLK) ! 2522: # ! 2523: # A CHARACTER TABLE BLOCK IS USED TO HOLD LOGICAL CHARACTER ! 2524: # TABLES FOR USE WITH ANY,NOTANY,SPAN,BREAK,BREAKX ! 2525: # PATTERNS. EACH CHARACTER TABLE CAN BE USED TO STORE ! 2526: # CFP$N DISTINCT TABLES AS BIT COLUMNS. A BIT COLUMN ! 2527: # ALLOCATED FOR EACH ARGUMENT OF MORE THAN ONE CHARACTER ! 2528: # IN LENGTH TO ONE OF THE ABOVE LISTED PATTERN PRIMITIVES. ! 2529: # ! 2530: # +------------------------------------+ ! 2531: # I CTTYP I ! 2532: # +------------------------------------+ ! 2533: # * * ! 2534: # * * ! 2535: # * CTCHS * ! 2536: # * * ! 2537: # * * ! 2538: # +------------------------------------+ ! 2539: # ! 2540: .set cttyp,0 # pointer to dummy routine b$ctt ! 2541: .set ctchs,cttyp+1 # start of character table words ! 2542: .set ctsi$,ctchs+cfp$a# number of words in ctblk ! 2543: # ! 2544: # CTCHS IS CFP$A WORDS LONG AND CONSISTS OF A ONE WORD ! 2545: # BIT STRING VALUE FOR EACH POSSIBLE CHARACTER IN THE ! 2546: # INTERNAL ALPHABET. EACH OF THE CFP$N POSSIBLE BITS IN ! 2547: # A BITSTRING IS USED TO FORM A COLUMN OF BIT INDICATORS. ! 2548: # A BIT IS SET ON IF THE CHARACTER IS IN THE TABLE AND OFF ! 2549: # IF THE CHARACTER IS NOT PRESENT. ! 2550: #page ! 2551: # ! 2552: # DATATYPE FUNCTION BLOCK (DFBLK) ! 2553: # ! 2554: # A DATATYPE FUNCTION IS USED TO CONTROL THE CONSTRUCTION ! 2555: # OF A PROGRAM DEFINED DATATYPE OBJECT. A CALL TO THE ! 2556: # SYSTEM FUNCTION DATA BUILDS A DFBLK FOR THE DATATYPE NAME ! 2557: # ! 2558: # NOTE THAT THESE BLOCKS ARE BUILT IN STATIC BECAUSE PDBLK ! 2559: # LENGTH IS GOT FROM DFLEN FIELD. IF DFBLK WAS IN DYNAMIC ! 2560: # STORE THIS WOULD CAUSE TROUBLE DURING PASS TWO OF GARBAGE ! 2561: # COLLECTION. SCBLK REFERRED TO BY DFNAM FIELD IS ALSO PUT ! 2562: # IN STATIC SO THAT THERE ARE NO RELOC. FIELDS. THIS CUTS ! 2563: # GARBAGE COLLECTION TASK APPRECIABLY FOR PDBLKS WHICH ARE ! 2564: # LIKELY TO BE PRESENT IN LARGE NUMBERS. ! 2565: # ! 2566: # +------------------------------------+ ! 2567: # I FCODE I ! 2568: # +------------------------------------+ ! 2569: # I FARGS I ! 2570: # +------------------------------------+ ! 2571: # I DFLEN I ! 2572: # +------------------------------------+ ! 2573: # I DFPDL I ! 2574: # +------------------------------------+ ! 2575: # I DFNAM I ! 2576: # +------------------------------------+ ! 2577: # / / ! 2578: # / DFFLD / ! 2579: # / / ! 2580: # +------------------------------------+ ! 2581: # ! 2582: .set dflen,fargs+1 # length of dfblk in bytes ! 2583: .set dfpdl,dflen+1 # length of corresponding pdblk ! 2584: .set dfnam,dfpdl+1 # pointer to scblk for datatype name ! 2585: .set dffld,dfnam+1 # start of vrblk ptrs for field names ! 2586: .set dfflb,dffld-1 # offset behind dffld for field func ! 2587: .set dfsi$,dffld # number of standard fields in dfblk ! 2588: # ! 2589: # THE FCODE FIELD POINTS TO THE ROUTINE B$DFC ! 2590: # ! 2591: # FARGS (THE NUMBER OF ARGUMENTS) IS THE NUMBER OF FIELDS. ! 2592: #page ! 2593: # ! 2594: # DOPE VECTOR BLOCK (DVBLK) ! 2595: # ! 2596: # A DOPE VECTOR IS ASSEMBLED FOR EACH POSSIBLE OPERATOR IN ! 2597: # THE SNOBOL4 LANGUAGE AS PART OF THE CONSTANT SECTION. ! 2598: # ! 2599: # +------------------------------------+ ! 2600: # I DVOPN I ! 2601: # +------------------------------------+ ! 2602: # I DVTYP I ! 2603: # +------------------------------------+ ! 2604: # I DVLPR I ! 2605: # +------------------------------------+ ! 2606: # I DVRPR I ! 2607: # +------------------------------------+ ! 2608: # ! 2609: .set dvopn,0 # entry address (ptr to o$xxx) ! 2610: .set dvtyp,dvopn+1 # type code (c$xxx, see cmblk) ! 2611: .set dvlpr,dvtyp+1 # left precedence (llxxx, see below) ! 2612: .set dvrpr,dvlpr+1 # right precedence (rrxxx, see below) ! 2613: .set dvus$,dvlpr+1 # size of unary operator dv ! 2614: .set dvbs$,dvrpr+1 # size of binary operator dv ! 2615: .set dvubs,dvus$+dvbs$# size of unop + binop (see scane) ! 2616: # ! 2617: # THE CONTENTS OF THE DVTYP FIELD IS COPIED INTO THE CMTYP ! 2618: # FIELD OF THE CMBLK FOR THE OPERATOR IF IT IS USED. ! 2619: # ! 2620: # THE CMOPN FIELD OF AN OPERATOR CMBLK POINTS TO THE DVBLK ! 2621: # ITSELF, PROVIDING THE REQUIRED ENTRY ADDRESS POINTER PTR. ! 2622: # ! 2623: # FOR NORMALLY UNDEFINED OPERATORS, THE DVOPN (AND CMOPN) ! 2624: # FIELDS CONTAIN A WORD OFFSET FROM R$UBA OF THE FUNCTION ! 2625: # BLOCK POINTER FOR THE OPERATOR (INSTEAD OF O$XXX PTR). ! 2626: # FOR CERTAIN SPECIAL OPERATORS, THE DVOPN FIELD IS NOT ! 2627: # REQUIRED AT ALL AND IS ASSEMBLED AS ZERO. ! 2628: # ! 2629: # THE LEFT PRECEDENCE IS USED IN COMPARING AN OPERATOR TO ! 2630: # THE LEFT OF SOME OTHER OPERATOR. IT THEREFORE GOVERNS THE ! 2631: # PRECEDENCE OF THE OPERATOR TOWARDS ITS RIGHT OPERAND. ! 2632: # ! 2633: # THE RIGHT PRECEDENCE IS USED IN COMPARING AN OPERATOR TO ! 2634: # THE RIGHT OF SOME OTHER OPERATOR. IT THEREFORE GOVERNS ! 2635: # THE PRECEDENCE OF THE OPERATOR TOWARDS ITS LEFT OPERAND. ! 2636: # ! 2637: # HIGHER PRECEDENCE VALUES CORRESPOND TO A TIGHTER BINDING ! 2638: # CAPABILITY. THUS WE HAVE THE LEFT PRECEDENCE LOWER ! 2639: # (HIGHER) THAN THE RIGHT PRECEDENCE FOR RIGHT (LEFT) ! 2640: # ASSOCIATIVE BINARY OPERATORS. ! 2641: # ! 2642: # THE LEFT PRECEDENCE OF UNARY OPERATORS IS SET TO AN ! 2643: # ARBITRARY HIGH VALUE. THE RIGHT VALUE IS NOT REQUIRED AND ! 2644: # CONSEQUENTLY THE DVRPR FIELD IS OMITTED FOR UNARY OPS. ! 2645: #page ! 2646: # ! 2647: # TABLE OF OPERATOR PRECEDENCE VALUES ! 2648: # ! 2649: .set rrass,10 # right equal ! 2650: .set llass,00 # left equal ! 2651: .set rrpmt,20 # right question mark ! 2652: .set llpmt,30 # left question mark ! 2653: .set rramp,40 # right ampersand ! 2654: .set llamp,50 # left ampersand ! 2655: .set rralt,70 # right vertical bar ! 2656: .set llalt,60 # left vertical bar ! 2657: .set rrcnc,90 # right blank ! 2658: .set llcnc,80 # left blank ! 2659: .set rrats,110 # right at ! 2660: .set llats,100 # left at ! 2661: .set rrplm,120 # right plus, minus ! 2662: .set llplm,130 # left plus, minus ! 2663: .set rrnum,140 # right number ! 2664: .set llnum,150 # left number ! 2665: .set rrdvd,160 # right slash ! 2666: .set lldvd,170 # left slash ! 2667: .set rrmlt,180 # right asterisk ! 2668: .set llmlt,190 # left asterisk ! 2669: .set rrpct,200 # right percent ! 2670: .set llpct,210 # left percent ! 2671: .set rrexp,230 # right exclamation ! 2672: .set llexp,220 # left exclamation ! 2673: .set rrdld,240 # right dollar, dot ! 2674: .set lldld,250 # left dollar, dot ! 2675: .set rrnot,270 # right not ! 2676: .set llnot,260 # left not ! 2677: .set lluno,999 # left all unary operators ! 2678: # ! 2679: # PRECEDENCES ARE THE SAME AS IN BTL SNOBOL4 WITH THE ! 2680: # FOLLOWING EXCEPTIONS. ! 2681: # ! 2682: # 1) BINARY QUESTION MARK IS LOWERED AND MADE LEFT ASSOC- ! 2683: # IATIVE TO REFLECT ITS NEW USE FOR PATTERN MATCHING. ! 2684: # ! 2685: # 2) ALTERNATION AND CONCATENATION ARE MADE RIGHT ! 2686: # ASSOCIATIVE FOR GREATER EFFICIENCY IN PATTERN ! 2687: # CONSTRUCTION AND MATCHING RESPECTIVELY. THIS CHANGE ! 2688: # IS TRANSPARENT TO THE SNOBOL4 PROGRAMMER. ! 2689: # ! 2690: # 3) THE EQUAL SIGN HAS BEEN ADDED AS A LOW PRECEDENCE ! 2691: # OPERATOR WHICH IS RIGHT ASSOCIATIVE TO REFLECT ITS ! 2692: # MORE GENERAL USAGE IN THIS VERSION OF SNOBOL4. ! 2693: #page ! 2694: # ! 2695: # EXTERNAL FUNCTION BLOCK (EFBLK) ! 2696: # ! 2697: # AN EXTERNAL FUNCTION BLOCK IS USED TO CONTROL THE CALLING ! 2698: # OF AN EXTERNAL FUNCTION. IT IS BUILT BY A CALL TO LOAD. ! 2699: # ! 2700: # +------------------------------------+ ! 2701: # I FCODE I ! 2702: # +------------------------------------+ ! 2703: # I FARGS I ! 2704: # +------------------------------------+ ! 2705: # I EFLEN I ! 2706: # +------------------------------------+ ! 2707: # I EFUSE I ! 2708: # +------------------------------------+ ! 2709: # I EFCOD I ! 2710: # +------------------------------------+ ! 2711: # I EFVAR I ! 2712: # +------------------------------------+ ! 2713: # I EFRSL I ! 2714: # +------------------------------------+ ! 2715: # / / ! 2716: # / EFTAR / ! 2717: # / / ! 2718: # +------------------------------------+ ! 2719: # ! 2720: .set eflen,fargs+1 # length of efblk in bytes ! 2721: .set efuse,eflen+1 # use count (for opsyn) ! 2722: .set efcod,efuse+1 # ptr to code (from sysld) ! 2723: .set efvar,efcod+1 # ptr to associated vrblk ! 2724: .set efrsl,efvar+1 # result type (see below) ! 2725: .set eftar,efrsl+1 # argument types (see below) ! 2726: .set efsi$,eftar # number of standard fields in efblk ! 2727: # ! 2728: # THE FCODE FIELD POINTS TO THE ROUTINE B$EFC. ! 2729: # ! 2730: # EFUSE IS USED TO KEEP TRACK OF MULTIPLE USE WHEN OPSYN ! 2731: # IS EMPLOYED. THE FUNCTION IS AUTOMATICALLY UNLOADED ! 2732: # WHEN THERE ARE NO MORE REFERENCES TO THE FUNCTION. ! 2733: # ! 2734: # EFRSL AND EFTAR ARE TYPE CODES AS FOLLOWS. ! 2735: # ! 2736: # 0 TYPE IS UNCONVERTED ! 2737: # 1 TYPE IS STRING ! 2738: # 2 TYPE IS INTEGER ! 2739: # 3 TYPE IS REAL ! 2740: #page ! 2741: # ! 2742: # EXPRESSION VARIABLE BLOCK (EVBLK) ! 2743: # ! 2744: # IN THIS VERSION OF SPITBOL, AN EXPRESSION CAN BE USED IN ! 2745: # ANY POSITION WHICH WOULD NORMALLY EXPECT A NAME (FOR ! 2746: # EXAMPLE ON THE LEFT SIDE OF EQUALS OR AS THE RIGHT ! 2747: # ARGUMENT OF BINARY DOT). THIS CORRESPONDS TO THE CREATION ! 2748: # OF A PSEUDO-VARIABLE WHICH IS REPRESENTED BY A POINTER TO ! 2749: # AN EXPRESSION VARIABLE BLOCK AS FOLLOWS. ! 2750: # ! 2751: # +------------------------------------+ ! 2752: # I EVTYP I ! 2753: # +------------------------------------+ ! 2754: # I EVEXP I ! 2755: # +------------------------------------+ ! 2756: # I EVVAR I ! 2757: # +------------------------------------+ ! 2758: # ! 2759: .set evtyp,0 # pointer to dummy routine b$evt ! 2760: .set evexp,evtyp+1 # pointer to exblk for expression ! 2761: .set evvar,evexp+1 # pointer to trbev dummy trblk ! 2762: .set evsi$,evvar+1 # size of evblk ! 2763: # ! 2764: # THE NAME OF AN EXPRESSION VARIABLE IS REPRESENTED BY A ! 2765: # BASE POINTER TO THE EVBLK AND AN OFFSET OF EVVAR. THIS ! 2766: # VALUE APPEARS TO BE TRAPPED BY THE DUMMY TRBEV BLOCK. ! 2767: # ! 2768: # NOTE THAT THERE IS NO NEED TO ALLOW FOR THE CASE OF AN ! 2769: # EXPRESSION VARIABLE WHICH REFERENCES AN SEBLK SINCE A ! 2770: # VARIABLE WHICH IS OF THE FORM *VAR IS EQUIVALENT TO VAR. ! 2771: #page ! 2772: # ! 2773: # EXPRESSION BLOCK (EXBLK) ! 2774: # ! 2775: # AN EXPRESSION BLOCK IS BUILT FOR EACH EXPRESSION ! 2776: # REFERENCED IN A PROGRAM OR CREATED BY EVAL OR CONVERT ! 2777: # DURING EXECUTION OF A PROGRAM. ! 2778: # ! 2779: # +------------------------------------+ ! 2780: # I EXTYP I ! 2781: # +------------------------------------+ ! 2782: # I EXSTM I ! 2783: # +------------------------------------+ ! 2784: # I EXLEN I ! 2785: # +------------------------------------+ ! 2786: # I EXFLC I ! 2787: # +------------------------------------+ ! 2788: # / / ! 2789: # / EXCOD / ! 2790: # / / ! 2791: # +------------------------------------+ ! 2792: # ! 2793: .set extyp,0 # ptr to routine b$exl to load expr ! 2794: .set exstm,cdstm # stores stmnt no. during evaluation ! 2795: .set exlen,exstm+1 # length of exblk in bytes ! 2796: .set exflc,exlen+1 # failure code (=o$fex) ! 2797: .set excod,exflc+1 # pseudo-code for expression ! 2798: .set exsi$,excod # number of standard fields in exblk ! 2799: # ! 2800: # THERE ARE TWO CASES FOR EXCOD DEPENDING ON WHETHER THE ! 2801: # EXPRESSION CAN BE EVALUATED BY NAME (SEE DESCRIPTION ! 2802: # OF CDBLK FOR DETAILS OF CODE FOR EXPRESSIONS). ! 2803: # ! 2804: # IF THE EXPRESSION CAN BE EVALUATED BY NAME WE HAVE. ! 2805: # ! 2806: # (CODE FOR EXPR BY NAME) ! 2807: # =O$RNM ! 2808: # ! 2809: # IF THE EXPRESSION CAN ONLY BE EVALUATED BY VALUE. ! 2810: # ! 2811: # (CODE FOR EXPR BY VALUE) ! 2812: # =O$RVL ! 2813: #page ! 2814: # ! 2815: # FIELD FUNCTION BLOCK (FFBLK) ! 2816: # ! 2817: # A FIELD FUNCTION BLOCK IS USED TO CONTROL THE SELECTION ! 2818: # OF A FIELD FROM A PROGRAM DEFINED DATATYPE BLOCK. ! 2819: # A CALL TO DATA CREATES AN FFBLK FOR EACH FIELD. ! 2820: # ! 2821: # +------------------------------------+ ! 2822: # I FCODE I ! 2823: # +------------------------------------+ ! 2824: # I FARGS I ! 2825: # +------------------------------------+ ! 2826: # I FFDFP I ! 2827: # +------------------------------------+ ! 2828: # I FFNXT I ! 2829: # +------------------------------------+ ! 2830: # I FFOFS I ! 2831: # +------------------------------------+ ! 2832: # ! 2833: .set ffdfp,fargs+1 # pointer to associated dfblk ! 2834: .set ffnxt,ffdfp+1 # ptr to next ffblk on chain or zero ! 2835: .set ffofs,ffnxt+1 # offset (bytes) to field in pdblk ! 2836: .set ffsi$,ffofs+1 # size of ffblk in words ! 2837: # ! 2838: # THE FCODE FIELD POINTS TO THE ROUTINE B$FFC. ! 2839: # ! 2840: # FARGS ALWAYS CONTAINS ONE. ! 2841: # ! 2842: # FFDFP IS USED TO VERIFY THAT THE CORRECT PROGRAM DEFINED ! 2843: # DATATYPE IS BEING ACCESSED BY THIS CALL. ! 2844: # FFDFP IS NON-RELOC. BECAUSE DFBLK IS IN STATIC ! 2845: # ! 2846: # FFOFS IS USED TO SELECT THE APPROPRIATE FIELD. NOTE THAT ! 2847: # IT IS AN ACTUAL OFFSET (NOT A FIELD NUMBER) ! 2848: # ! 2849: # FFNXT IS USED TO POINT TO THE NEXT FFBLK OF THE SAME NAME ! 2850: # IN THE CASE WHERE THERE ARE SEVERAL FIELDS OF THE SAME ! 2851: # NAME FOR DIFFERENT DATATYPES. ZERO MARKS THE END OF CHAIN ! 2852: #page ! 2853: # ! 2854: # INTEGER CONSTANT BLOCK (ICBLK) ! 2855: # ! 2856: # AN ICBLK IS CREATED FOR EVERY INTEGER REFERENCED OR ! 2857: # CREATED BY A PROGRAM. NOTE HOWEVER THAT CERTAIN INTERNAL ! 2858: # INTEGER VALUES ARE STORED AS ADDRESSES (E.G. THE LENGTH ! 2859: # FIELD IN A STRING CONSTANT BLOCK) ! 2860: # ! 2861: # +------------------------------------+ ! 2862: # I ICGET I ! 2863: # +------------------------------------+ ! 2864: # * ICVAL * ! 2865: # +------------------------------------+ ! 2866: # ! 2867: .set icget,0 # ptr to routine b$icl to load int ! 2868: .set icval,icget+1 # integer value ! 2869: .set icsi$,icval+cfp$i# size of icblk ! 2870: # ! 2871: # THE LENGTH OF THE ICVAL FIELD IS CFP$I. ! 2872: #page ! 2873: # ! 2874: # KEYWORD VARIABLE BLOCK (KVBLK) ! 2875: # ! 2876: # A KVBLK IS USED TO REPRESENT A KEYWORD PSEUDO-VARIABLE. ! 2877: # A KVBLK IS BUILT FOR EACH KEYWORD REFERENCE (KWNAM). ! 2878: # ! 2879: # +------------------------------------+ ! 2880: # I KVTYP I ! 2881: # +------------------------------------+ ! 2882: # I KVVAR I ! 2883: # +------------------------------------+ ! 2884: # I KVNUM I ! 2885: # +------------------------------------+ ! 2886: # ! 2887: .set kvtyp,0 # pointer to dummy routine b$kvt ! 2888: .set kvvar,kvtyp+1 # pointer to dummy block trbkv ! 2889: .set kvnum,kvvar+1 # keyword number ! 2890: .set kvsi$,kvnum+1 # size of kvblk ! 2891: # ! 2892: # THE NAME OF A KEYWORD VARIABLE IS REPRESENTED BY A ! 2893: # BASE POINTER TO THE KVBLK AND AN OFFSET OF KVVAR. THE ! 2894: # VALUE APPEARS TO BE TRAPPED BY THE POINTER TO TRBKV. ! 2895: #page ! 2896: # ! 2897: # NAME BLOCK (NMBLK) ! 2898: # ! 2899: # A NAME BLOCK IS USED WHEREVER A NAME MUST BE STORED AS ! 2900: # A VALUE FOLLOWING USE OF THE UNARY DOT OPERATOR. ! 2901: # ! 2902: # +------------------------------------+ ! 2903: # I NMTYP I ! 2904: # +------------------------------------+ ! 2905: # I NMBAS I ! 2906: # +------------------------------------+ ! 2907: # I NMOFS I ! 2908: # +------------------------------------+ ! 2909: # ! 2910: .set nmtyp,0 # ptr to routine b$nml to load name ! 2911: .set nmbas,nmtyp+1 # base pointer for variable ! 2912: .set nmofs,nmbas+1 # offset for variable ! 2913: .set nmsi$,nmofs+1 # size of nmblk ! 2914: # ! 2915: # THE ACTUAL FIELD REPRESENTING THE CONTENTS OF THE NAME ! 2916: # IS FOUND NMOFS BYTES PAST THE ADDRESS IN NMBAS. ! 2917: # ! 2918: # THE NAME IS SPLIT INTO BASE AND OFFSET FORM TO AVOID ! 2919: # CREATION OF A POINTER INTO THE MIDDLE OF A BLOCK WHICH ! 2920: # COULD NOT BE HANDLED PROPERLY BY THE GARBAGE COLLECTOR. ! 2921: # ! 2922: # A NAME MAY BE BUILT FOR ANY VARIABLE (SEE SECTION ON ! 2923: # REPRESENTATIONS OF VARIABLES) THIS INCLUDES THE ! 2924: # CASES OF PSEUDO-VARIABLES. ! 2925: #page ! 2926: # ! 2927: # PATTERN BLOCK, NO PARAMETERS (P0BLK) ! 2928: # ! 2929: # A P0BLK IS USED TO REPRESENT PATTERN NODES WHICH DO ! 2930: # NOT REQUIRE THE USE OF ANY PARAMETER VALUES. ! 2931: # ! 2932: # +------------------------------------+ ! 2933: # I PCODE I ! 2934: # +------------------------------------+ ! 2935: # I PTHEN I ! 2936: # +------------------------------------+ ! 2937: # ! 2938: .set pcode,0 # ptr to match routine (p$xxx) ! 2939: .set pthen,pcode+1 # pointer to subsequent node ! 2940: .set pasi$,pthen+1 # size of p0blk ! 2941: # ! 2942: # PTHEN POINTS TO THE PATTERN BLOCK FOR THE SUBSEQUENT ! 2943: # NODE TO BE MATCHED. THIS IS A POINTER TO THE PATTERN ! 2944: # BLOCK NDNTH IF THERE IS NO SUBSEQUENT (END OF PATTERN) ! 2945: # ! 2946: # PCODE IS A POINTER TO THE MATCH ROUTINE FOR THE NODE. ! 2947: #page ! 2948: # ! 2949: # PATTERN BLOCK (ONE PARAMETER) ! 2950: # ! 2951: # A P1BLK IS USED TO REPRESENT PATTERN NODES WHICH ! 2952: # REQUIRE ONE PARAMETER VALUE. ! 2953: # ! 2954: # +------------------------------------+ ! 2955: # I PCODE I ! 2956: # +------------------------------------+ ! 2957: # I PTHEN I ! 2958: # +------------------------------------+ ! 2959: # I PARM1 I ! 2960: # +------------------------------------+ ! 2961: # ! 2962: .set parm1,pthen+1 # first parameter value ! 2963: .set pbsi$,parm1+1 # size of p1blk in words ! 2964: # ! 2965: # SEE P0BLK FOR DEFINITIONS OF PCODE, PTHEN ! 2966: # ! 2967: # PARM1 CONTAINS A PARAMETER VALUE USED IN MATCHING THE ! 2968: # NODE. FOR EXAMPLE, IN A LEN PATTERN, IT IS THE INTEGER ! 2969: # ARGUMENT TO LEN. THE DETAILS OF THE USE OF THE PARAMETER ! 2970: # FIELD ARE INCLUDED IN THE DESCRIPTION OF THE INDIVIDUAL ! 2971: # MATCH ROUTINES. PARM1 IS ALWAYS AN ADDRESS POINTER WHICH ! 2972: # IS PROCESSED BY THE GARBAGE COLLECTOR. ! 2973: #page ! 2974: # ! 2975: # PATTERN BLOCK (TWO PARAMETERS) ! 2976: # ! 2977: # A P2BLK IS USED TO REPRESENT PATTERN NODES WHICH ! 2978: # REQUIRE TWO PARAMETER VALUES. ! 2979: # ! 2980: # +------------------------------------+ ! 2981: # I PCODE I ! 2982: # +------------------------------------+ ! 2983: # I PTHEN I ! 2984: # +------------------------------------+ ! 2985: # I PARM1 I ! 2986: # +------------------------------------+ ! 2987: # I PARM2 I ! 2988: # +------------------------------------+ ! 2989: # ! 2990: .set parm2,parm1+1 # second parameter value ! 2991: .set pcsi$,parm2+1 # size of p2blk in words ! 2992: # ! 2993: # SEE P1BLK FOR DEFINITIONS OF PCODE, PTHEN, PARM1 ! 2994: # ! 2995: # PARM2 IS A PARAMETER WHICH PERFORMS THE SAME SORT OF ! 2996: # FUNCTION AS PARM1 (SEE DESCRIPTION OF P1BLK). ! 2997: # ! 2998: # PARM2 IS A NON-RELOCATABLE FIELD AND IS NOT ! 2999: # PROCESSED BY THE GARBAGE COLLECTOR. ACCORDINGLY, IT MAY ! 3000: # NOT CONTAIN A POINTER TO A BLOCK IN DYNAMIC MEMORY. ! 3001: #page ! 3002: # ! 3003: # PROGRAM-DEFINED DATATYPE BLOCK ! 3004: # ! 3005: # A PDBLK REPRESENTS THE DATA ITEM FORMED BY A CALL TO A ! 3006: # DATATYPE FUNCTION AS DEFINED BY THE SYSTEM FUNCTION DATA. ! 3007: # ! 3008: # +------------------------------------+ ! 3009: # I PDTYP I ! 3010: # +------------------------------------+ ! 3011: # I IDVAL I ! 3012: # +------------------------------------+ ! 3013: # I PDDFP I ! 3014: # +------------------------------------+ ! 3015: # / / ! 3016: # / PDFLD / ! 3017: # / / ! 3018: # +------------------------------------+ ! 3019: # ! 3020: .set pdtyp,0 # ptr to dummy routine b$pdt ! 3021: .set pddfp,idval+1 # ptr to associated dfblk ! 3022: .set pdfld,pddfp+1 # start of field value pointers ! 3023: .set pdfof,dffld-pdfld# difference in offset to field ptrs ! 3024: .set pdsi$,pdfld # size of standard fields in pdblk ! 3025: .set pddfs,dfsi$-pdsi$# difference in dfblk, pdblk sizes ! 3026: # ! 3027: # THE PDDFP POINTER MAY BE USED TO DETERMINE THE DATATYPE ! 3028: # AND THE NAMES OF THE FIELDS IF REQUIRED. THE DFBLK ALSO ! 3029: # CONTAINS THE LENGTH OF THE PDBLK IN BYTES (FIELD DFPDL). ! 3030: # PDDFP IS NON-RELOC. BECAUSE DFBLK IS IN STATIC ! 3031: # ! 3032: # PDFLD VALUES ARE STORED IN ORDER FROM LEFT TO RIGHT. ! 3033: # THEY CONTAIN VALUES OR POINTERS TO TRBLK CHAINS. ! 3034: #page ! 3035: # ! 3036: # PROGRAM DEFINED FUNCTION BLOCK (PFBLK) ! 3037: # ! 3038: # A PFBLK IS CREATED FOR EACH CALL TO THE DEFINE FUNCTION ! 3039: # AND A POINTER TO THE PFBLK PLACED IN THE PROPER VRBLK. ! 3040: # ! 3041: # +------------------------------------+ ! 3042: # I FCODE I ! 3043: # +------------------------------------+ ! 3044: # I FARGS I ! 3045: # +------------------------------------+ ! 3046: # I PFLEN I ! 3047: # +------------------------------------+ ! 3048: # I PFVBL I ! 3049: # +------------------------------------+ ! 3050: # I PFNLO I ! 3051: # +------------------------------------+ ! 3052: # I PFCOD I ! 3053: # +------------------------------------+ ! 3054: # I PFCTR I ! 3055: # +------------------------------------+ ! 3056: # I PFRTR I ! 3057: # +------------------------------------+ ! 3058: # / / ! 3059: # / PFARG / ! 3060: # / / ! 3061: # +------------------------------------+ ! 3062: # ! 3063: .set pflen,fargs+1 # length of pfblk in bytes ! 3064: .set pfvbl,pflen+1 # pointer to vrblk for function name ! 3065: .set pfnlo,pfvbl+1 # number of locals ! 3066: .set pfcod,pfnlo+1 # ptr to cdblk for first statement ! 3067: .set pfctr,pfcod+1 # trblk ptr if call traced else 0 ! 3068: .set pfrtr,pfctr+1 # trblk ptr if return traced else 0 ! 3069: .set pfarg,pfrtr+1 # vrblk ptrs for arguments and locals ! 3070: .set pfagb,pfarg-1 # offset behind pfarg for arg, local ! 3071: .set pfsi$,pfarg # number of standard fields in pfblk ! 3072: # ! 3073: # THE FCODE FIELD POINTS TO THE ROUTINE B$PFC. ! 3074: # ! 3075: # PFARG IS STORED IN THE FOLLOWING ORDER. ! 3076: # ! 3077: # ARGUMENTS (LEFT TO RIGHT) ! 3078: # LOCALS (LEFT TO RIGHT) ! 3079: #page ! 3080: # ! 3081: # REAL CONSTANT BLOCK (RCBLK) ! 3082: # ! 3083: # AN RCBLK IS CREATED FOR EVERY REAL REFERENCED OR ! 3084: # CREATED BY A PROGRAM. ! 3085: # ! 3086: # +------------------------------------+ ! 3087: # I RCGET I ! 3088: # +------------------------------------+ ! 3089: # * RCVAL * ! 3090: # +------------------------------------+ ! 3091: # ! 3092: .set rcget,0 # ptr to routine b$rcl to load real ! 3093: .set rcval,rcget+1 # real value ! 3094: .set rcsi$,rcval+cfp$r# size of rcblk ! 3095: # ! 3096: # THE LENGTH OF THE RCVAL FIELD IS CFP$R. ! 3097: #page ! 3098: # ! 3099: # STRING CONSTANT BLOCK (SCBLK) ! 3100: # ! 3101: # AN SCBLK IS BUILT FOR EVERY STRING REFERENCED OR CREATED ! 3102: # BY A PROGRAM. ! 3103: # ! 3104: # +------------------------------------+ ! 3105: # I SCGET I ! 3106: # +------------------------------------+ ! 3107: # I SCLEN I ! 3108: # +------------------------------------+ ! 3109: # / / ! 3110: # / SCHAR / ! 3111: # / / ! 3112: # +------------------------------------+ ! 3113: # ! 3114: .set scget,0 # ptr to routine b$scl to load string ! 3115: .set sclen,scget+1 # length of string in characters ! 3116: .set schar,sclen+1 # characters of string ! 3117: .set scsi$,schar # size of standard fields in scblk ! 3118: # ! 3119: # THE CHARACTERS OF THE STRING ARE STORED LEFT JUSTIFIED. ! 3120: # THE FINAL WORD IS PADDED ON THE RIGHT WITH ZEROS. ! 3121: # (I.E. THE CHARACTER WHOSE INTERNAL CODE IS ZERO). ! 3122: # ! 3123: # THE VALUE OF SCLEN MAY NOT EXCEED MXLEN. THIS ENSURES ! 3124: # THAT CHARACTER OFFSETS (E.G. THE PATTERN MATCH CURSOR) ! 3125: # CAN BE CORRECTLY PROCESSED BY THE GARBAGE COLLECTOR. ! 3126: # ! 3127: # NOTE THAT THE OFFSET TO THE CHARACTERS OF THE STRING ! 3128: # IS GIVEN IN BYTES BY CFP$F AND THAT THIS VALUE IS ! 3129: # AUTOMATICALLY ALLOWED FOR IN PLC, PSC. ! 3130: # NOTE THAT FOR A SPITBOL SCBLK, THE VALUE OF CFP$F ! 3131: # IS GIVEN BY CFP$B*SCHAR. ! 3132: #page ! 3133: # ! 3134: # SIMPLE EXPRESSION BLOCK (SEBLK) ! 3135: # ! 3136: # AN SEBLK IS USED TO REPRESENT AN EXPRESSION OF THE FORM ! 3137: # *(NATURAL VARIABLE). ALL OTHER EXPRESSIONS ARE EXBLKS. ! 3138: # ! 3139: # +------------------------------------+ ! 3140: # I SETYP I ! 3141: # +------------------------------------+ ! 3142: # I SEVAR I ! 3143: # +------------------------------------+ ! 3144: # ! 3145: .set setyp,0 # ptr to routine b$sel to load expr ! 3146: .set sevar,setyp+1 # ptr to vrblk for variable ! 3147: .set sesi$,sevar+1 # length of seblk in words ! 3148: #page ! 3149: # ! 3150: # STANDARD VARIABLE BLOCK (SVBLK) ! 3151: # ! 3152: # AN SVBLK IS ASSEMBLED IN THE CONSTANT SECTION FOR EACH ! 3153: # VARIABLE WHICH SATISFIES ONE OF THE FOLLOWING CONDITIONS. ! 3154: # ! 3155: # 1) IT IS THE NAME OF A SYSTEM FUNCTION ! 3156: # 2) IT HAS AN INITIAL VALUE ! 3157: # 3) IT HAS A KEYWORD ASSOCIATION ! 3158: # 4) IT HAS A STANDARD I/O ASSOCIATION ! 3159: # 6) IT HAS A STANDARD LABEL ASSOCIATION ! 3160: # ! 3161: # IF VRBLKS ARE CONSTRUCTED FOR ANY OF THESE VARIABLES, ! 3162: # THEN THE VRSVP FIELD POINTS TO THE SVBLK (SEE VRBLK) ! 3163: # ! 3164: # +------------------------------------+ ! 3165: # I SVBIT I ! 3166: # +------------------------------------+ ! 3167: # I SVLEN I ! 3168: # +------------------------------------+ ! 3169: # I SVCHS I ! 3170: # +------------------------------------+ ! 3171: # I SVKNM I ! 3172: # +------------------------------------+ ! 3173: # I SVFNC I ! 3174: # +------------------------------------+ ! 3175: # I SVNAR I ! 3176: # +------------------------------------+ ! 3177: # I SVLBL I ! 3178: # +------------------------------------+ ! 3179: # I SVVAL I ! 3180: # +------------------------------------+ ! 3181: #page ! 3182: # ! 3183: # STANDARD VARIABLE BLOCK (CONTINUED) ! 3184: # ! 3185: .set svbit,0 # bit string indicating attributes ! 3186: .set svlen,1 # (=sclen) length of name in chars ! 3187: .set svchs,2 # (=schar) characters of name ! 3188: .set svsi$,2 # number of standard fields in svblk ! 3189: .set svpre,1 # set if preevaluation permitted ! 3190: .set svffc,svpre+svpre# set on if fast call permitted ! 3191: .set svckw,svffc+svffc# set on if keyword value constant ! 3192: .set svprd,svckw+svckw# set on if predicate function ! 3193: .set svnbt,4 # number of bits to right of svknm ! 3194: .set svknm,svprd+svprd# set on if keyword association ! 3195: .set svfnc,svknm+svknm# set on if system function ! 3196: .set svnar,svfnc+svfnc# set on if system function ! 3197: .set svlbl,svnar+svnar# set on if system label ! 3198: .set svval,svlbl+svlbl# set on if predefined value ! 3199: # ! 3200: # NOTE THAT THE LAST FIVE BITS CORRESPOND IN ORDER ! 3201: # TO THE FIELDS WHICH ARE PRESENT (SEE PROCEDURE GTNVR). ! 3202: # ! 3203: # THE FOLLOWING DEFINITIONS ARE USED IN THE SVBLK TABLE ! 3204: # ! 3205: .set svfnf,svfnc+svnar# function with no fast call ! 3206: .set svfnn,svfnf+svffc# function with fast call, no preeval ! 3207: .set svfnp,svfnn+svpre# function allowing preevaluation ! 3208: .set svfpr,svfnn+svprd# predicate function ! 3209: .set svfnk,svfnn+svknm# no preeval func + keyword ! 3210: .set svkwv,svknm+svval# keyword + value ! 3211: .set svkwc,svckw+svknm# keyword with constant value ! 3212: .set svkvc,svkwv+svckw# constant keyword + value ! 3213: .set svkvl,svkvc+svlbl# constant keyword + value + label ! 3214: .set svfpk,svfnp+svkvc# preeval fcn + const keywd + val ! 3215: # ! 3216: # THE SVPRE BIT ALLOWS THE COMPILER TO PREEVALUATE A CALL ! 3217: # TO THE ASSOCIATED SYSTEM FUNCTION IF ALL THE ARGUMENTS ! 3218: # ARE THEMSELVES CONSTANTS. FUNCTIONS IN THIS CATEGORY ! 3219: # MUST HAVE NO SIDE EFFECTS AND MUST NEVER CAUSE FAILURE. ! 3220: # THE CALL MAY GENERATE AN ERROR CONDITION. ! 3221: # ! 3222: # THE SVFFC BIT ALLOWS THE COMPILER TO GENERATE THE SPECIAL ! 3223: # FAST CALL AFTER ADJUSTING THE NUMBER OF ARGUMENTS. ONLY ! 3224: # THE ITEM AND APPLY FUNCTIONS FALL OUTSIDE THIS CATEGORY. ! 3225: # ! 3226: # THE SVCKW BIT IS SET IF THE ASSOCIATED KEYWORD VALUE IS ! 3227: # A CONSTANT, THUS ALLOWING PREEVALUATION FOR A VALUE CALL. ! 3228: # ! 3229: # THE SVPRD BIT IS SET ON FOR ALL PREDICATE FUNCTIONS TO ! 3230: # ENABLE THE SPECIAL CONCATENATION CODE OPTIMIZATION. ! 3231: #page ! 3232: # ! 3233: # SVBLK (CONTINUED) ! 3234: # ! 3235: # SVKNM KEYWORD NUMBER ! 3236: # ! 3237: # SVKNM IS PRESENT ONLY FOR A STANDARD KEYWORD ASSOC. ! 3238: # IT CONTAINS A KEYWORD NUMBER AS DEFINED BY THE ! 3239: # KEYWORD NUMBER TABLE GIVEN LATER ON. ! 3240: # ! 3241: # SVFNC SYSTEM FUNCTION POINTER ! 3242: # ! 3243: # SVFNC IS PRESENT ONLY FOR A SYSTEM FUNCTION ASSOC. ! 3244: # IT IS A POINTER TO THE ACTUAL CODE FOR THE SYSTEM ! 3245: # FUNCTION. THE GENERATED CODE FOR A FAST CALL IS A ! 3246: # POINTER TO THE SVFNC FIELD OF THE SVBLK FOR THE ! 3247: # FUNCTION. THE VRFNC FIELD OF THE VRBLK POINTS TO ! 3248: # THIS SAME FIELD, IN WHICH CASE, IT SERVES AS THE ! 3249: # FCODE FIELD FOR THE FUNCTION CALL. ! 3250: # ! 3251: # SVNAR NUMBER OF FUNCTION ARGUMENTS ! 3252: # ! 3253: # SVNAR IS PRESENT ONLY FOR A SYSTEM FUNCTION ASSOC. ! 3254: # IT IS THE NUMBER OF ARGUMENTS REQUIRED FOR A CALL ! 3255: # TO THE SYSTEM FUNCTION. THE COMPILER USES THIS ! 3256: # VALUE TO ADJUST THE NUMBER OF ARGUMENTS IN A FAST ! 3257: # CALL AND IN THE CASE OF A FUNCTION CALLED THROUGH ! 3258: # THE VRFNC FIELD OF THE VRBLK, THE SVNAR FIELD ! 3259: # SERVES AS THE FARGS FIELD FOR O$FNC. A SPECIAL ! 3260: # CASE OCCURS IF THIS VALUE IS SET TO 999. THIS IS ! 3261: # USED TO INDICATE THAT THE FUNCTION HAS A VARIABLE ! 3262: # NUMBER OF ARGUMENTS AND CAUSES O$FNC TO PASS CONTROL ! 3263: # WITHOUT ADJUSTING THE ARGUMENT COUNT. THE ONLY ! 3264: # PREDEFINED FUNCTIONS USING THIS ARE APPLY AND ITEM. ! 3265: # ! 3266: # SVLBL SYSTEM LABEL POINTER ! 3267: # ! 3268: # SVLBL IS PRESENT ONLY FOR A STANDARD LABEL ASSOC. ! 3269: # IT IS A POINTER TO A SYSTEM LABEL ROUTINE (L$XXX). ! 3270: # THE VRLBL FIELD OF THE CORRESPONDING VRBLK POINTS TO ! 3271: # THE SVLBL FIELD OF THE SVBLK. ! 3272: # ! 3273: # SVVAL SYSTEM VALUE POINTER ! 3274: # ! 3275: # SVVAL IS PRESENT ONLY FOR A STANDARD VALUE. ! 3276: # IT IS A POINTER TO THE PATTERN NODE (NDXXX) WHICH ! 3277: # IS THE STANDARD INITIAL VALUE OF THE VARIABLE. ! 3278: # THIS VALUE IS COPIED TO THE VRVAL FIELD OF THE VRBLK ! 3279: #page ! 3280: # ! 3281: # SVBLK (CONTINUED) ! 3282: # ! 3283: # KEYWORD NUMBER TABLE ! 3284: # ! 3285: # THE FOLLOWING TABLE GIVES SYMBOLIC NAMES FOR KEYWORD ! 3286: # NUMBERS. THESE VALUES ARE STORED IN THE SVKNM FIELD OF ! 3287: # SVBLKS AND IN THE KVNUM FIELD OF KVBLKS. SEE ALSO ! 3288: # PROCEDURES ASIGN, ACESS AND KWNAM. ! 3289: # ! 3290: # UNPROTECTED KEYWORDS WITH ONE WORD INTEGER VALUES ! 3291: # ! 3292: .set k$abe,0 # abend ! 3293: .set k$anc,k$abe+cfp$b# anchor ! 3294: .set k$cas,k$anc+cfp$b# case ! 3295: .set k$cod,k$cas+cfp$b# code ! 3296: .set k$dmp,k$cod+cfp$b# dump ! 3297: .set k$erl,k$dmp+cfp$b# errlimit ! 3298: .set k$ert,k$erl+cfp$b# errtype ! 3299: .set k$ftr,k$ert+cfp$b# ftrace ! 3300: .set k$inp,k$ftr+cfp$b# input ! 3301: .set k$mxl,k$inp+cfp$b# maxlength ! 3302: .set k$oup,k$mxl+cfp$b# output ! 3303: .set k$pfl,k$oup+cfp$b# profile ! 3304: .set k$tra,k$pfl+cfp$b# trace ! 3305: .set k$trm,k$tra+cfp$b# trim ! 3306: # ! 3307: # PROTECTED KEYWORDS WITH ONE WORD INTEGER VALUES ! 3308: # ! 3309: .set k$fnc,k$trm+cfp$b# fnclevel ! 3310: .set k$lst,k$fnc+cfp$b# lastno ! 3311: .set k$stn,k$lst+cfp$b# stno ! 3312: # ! 3313: # KEYWORDS WITH CONSTANT PATTERN VALUES ! 3314: # ! 3315: .set k$abo,k$stn+cfp$b# abort ! 3316: .set k$arb,k$abo+pasi$# arb ! 3317: .set k$bal,k$arb+pasi$# bal ! 3318: .set k$fal,k$bal+pasi$# fail ! 3319: .set k$fen,k$fal+pasi$# fence ! 3320: .set k$rem,k$fen+pasi$# rem ! 3321: .set k$suc,k$rem+pasi$# succeed ! 3322: #page ! 3323: # ! 3324: # KEYWORD NUMBER TABLE (CONTINUED) ! 3325: # ! 3326: # SPECIAL KEYWORDS ! 3327: # ! 3328: .set k$alp,k$suc+1 # alphabet ! 3329: .set k$rtn,k$alp+1 # rtntype ! 3330: .set k$stc,k$rtn+1 # stcount ! 3331: .set k$etx,k$stc+1 # errtext ! 3332: .set k$stl,k$etx+1 # stlimit ! 3333: # ! 3334: # RELATIVE OFFSETS OF SPECIAL KEYWORDS ! 3335: # ! 3336: .set k$$al,k$alp-k$alp# alphabet ! 3337: .set k$$rt,k$rtn-k$alp# rtntype ! 3338: .set k$$sc,k$stc-k$alp# stcount ! 3339: .set k$$et,k$etx-k$alp# errtext ! 3340: .set k$$sl,k$stl-k$alp# stlimit ! 3341: # ! 3342: # SYMBOLS USED IN ASIGN AND ACESS PROCEDURES ! 3343: # ! 3344: .set k$p$$,k$fnc # first protected keyword ! 3345: .set k$v$$,k$abo # first keyword with constant value ! 3346: .set k$s$$,k$alp # first keyword with special acess ! 3347: #page ! 3348: # ! 3349: # FORMAT OF A TABLE BLOCK (TBBLK) ! 3350: # ! 3351: # A TABLE BLOCK IS USED TO REPRESENT A TABLE VALUE. ! 3352: # IT IS BUILT BY A CALL TO THE TABLE OR CONVERT FUNCTIONS. ! 3353: # ! 3354: # +------------------------------------+ ! 3355: # I TBTYP I ! 3356: # +------------------------------------+ ! 3357: # I IDVAL I ! 3358: # +------------------------------------+ ! 3359: # I TBLEN I ! 3360: # +------------------------------------+ ! 3361: # +------------------------------------+ ! 3362: # I TBINV I ! 3363: # +------------------------------------+ ! 3364: # / / ! 3365: # / TBBUK / ! 3366: # / / ! 3367: # +------------------------------------+ ! 3368: # ! 3369: .set tbtyp,0 # pointer to dummy routine b$tbt ! 3370: .set tblen,offs2 # length of tbblk in bytes ! 3371: .set tbinv,offs3 # default initial lookup value ! 3372: .set tbbuk,tbinv+1 # start of hash bucket pointers ! 3373: .set tbsi$,tbbuk # size of standard fields in tbblk ! 3374: .set tbnbk,11 # default no. of buckets ! 3375: # ! 3376: # THE TABLE BLOCK IS A HASH TABLE WHICH POINTS TO CHAINS ! 3377: # OF TABLE ELEMENT BLOCKS REPRESENTING THE ELEMENTS ! 3378: # IN THE TABLE WHICH HASH INTO THE SAME BUCKET. ! 3379: # ! 3380: # TBBUK ENTRIES EITHER POINT TO THE FIRST TEBLK ON THE ! 3381: # CHAIN OR THEY POINT TO THE TBBLK ITSELF TO INDICATE THE ! 3382: # END OF THE CHAIN. ! 3383: #page ! 3384: # ! 3385: # TABLE ELEMENT BLOCK (TEBLK) ! 3386: # ! 3387: # A TABLE ELEMENT IS USED TO REPRESENT A SINGLE ENTRY IN ! 3388: # A TABLE (SEE DESCRIPTION OF TBBLK FORMAT FOR HASH TABLE) ! 3389: # ! 3390: # +------------------------------------+ ! 3391: # I TETYP I ! 3392: # +------------------------------------+ ! 3393: # I TESUB I ! 3394: # +------------------------------------+ ! 3395: # I TEVAL I ! 3396: # +------------------------------------+ ! 3397: # I TENXT I ! 3398: # +------------------------------------+ ! 3399: # ! 3400: .set tetyp,0 # pointer to dummy routine b$tet ! 3401: .set tesub,tetyp+1 # subscript value ! 3402: .set teval,tesub+1 # (=vrval) table element value ! 3403: .set tenxt,teval+1 # link to next teblk ! 3404: # SEE S$CNV WHERE RELATION IS ASSUMED WITH TENXT AND TBBUK ! 3405: .set tesi$,tenxt+1 # size of teblk in words ! 3406: # ! 3407: # TENXT POINTS TO THE NEXT TEBLK ON THE HASH CHAIN FROM THE ! 3408: # TBBUK CHAIN FOR THIS HASH INDEX. AT THE END OF THE CHAIN, ! 3409: # TENXT POINTS BACK TO THE START OF THE TBBLK. ! 3410: # ! 3411: # TEVAL CONTAINS A DATA POINTER OR A TRBLK POINTER. ! 3412: # ! 3413: # TESUB CONTAINS A DATA POINTER. ! 3414: #page ! 3415: # ! 3416: # TRAP BLOCK (TRBLK) ! 3417: # ! 3418: # A TRAP BLOCK IS USED TO REPRESENT A TRACE OR INPUT OR ! 3419: # OUTPUT ASSOCIATION IN RESPONSE TO A CALL TO THE TRACE ! 3420: # INPUT OR OUTPUT SYSTEM FUNCTIONS. SEE BELOW FOR DETAILS ! 3421: # ! 3422: # +------------------------------------+ ! 3423: # I TRIDN I ! 3424: # +------------------------------------+ ! 3425: # I TRTYP I ! 3426: # +------------------------------------+ ! 3427: # I TRVAL OR TRLBL OR TRNXT OR TRKVR I ! 3428: # +------------------------------------+ ! 3429: # I TRTAG OR TRTER OR TRTRF I ! 3430: # +------------------------------------+ ! 3431: # I TRFNC OR TRFPT I ! 3432: # +------------------------------------+ ! 3433: # ! 3434: .set tridn,0 # pointer to dummy routine b$trt ! 3435: .set trtyp,tridn+1 # trap type code ! 3436: .set trval,trtyp+1 # value of trapped variable (=vrval) ! 3437: .set trnxt,trval # ptr to next trblk on trblk chain ! 3438: .set trlbl,trval # ptr to actual label (traced label) ! 3439: .set trkvr,trval # vrblk pointer for keyword trace ! 3440: .set trtag,trval+1 # trace tag ! 3441: .set trter,trtag # ptr to terminal vrblk or null ! 3442: .set trtrf,trtag # ptr to trblk holding fcblk ptr ! 3443: .set trfnc,trtag+1 # trace function vrblk (zero if none) ! 3444: .set trfpt,trfnc # fcblk ptr for sysio ! 3445: .set trsi$,trfnc+1 # number of words in trblk ! 3446: # ! 3447: .set trtin,0 # trace type for input association ! 3448: .set trtac,trtin+1 # trace type for access trace ! 3449: .set trtvl,trtac+1 # trace type for value trace ! 3450: .set trtou,trtvl+1 # trace type for output association ! 3451: .set trtfc,trtou+1 # trace type for fcblk identification ! 3452: #page ! 3453: # ! 3454: # TRAP BLOCK (CONTINUED) ! 3455: # ! 3456: # VARIABLE INPUT ASSOCIATION ! 3457: # ! 3458: # THE VALUE FIELD OF THE VARIABLE POINTS TO A TRBLK ! 3459: # INSTEAD OF CONTAINING THE DATA VALUE. IN THE CASE ! 3460: # OF A NATURAL VARIABLE, THE VRGET AND VRSTO FIELDS ! 3461: # CONTAIN =B$VRA AND =B$VRV TO ACTIVATE THE CHECK. ! 3462: # ! 3463: # TRTYP IS SET TO TRTIN ! 3464: # TRNXT POINTS TO NEXT TRBLK OR TRVAL HAS VARIABLE VAL ! 3465: # TRTER IS A POINTER TO SVBLK IF ASSOCIATION IS ! 3466: # FOR INPUT, TERMINAL, ELSE IT IS NULL. ! 3467: # TRTRF POINTS TO THE TRAP BLOCK WHICH IN TURN POINTS ! 3468: # TO AN FCBLK USED FOR I/O ASSOCIATION. ! 3469: # TRFPT IS THE FCBLK PTR RETURNED BY SYSIO. ! 3470: # ! 3471: # VARIABLE ACCESS TRACE ASSOCIATION ! 3472: # ! 3473: # THE VALUE FIELD OF THE VARIABLE POINTS TO A TRBLK ! 3474: # INSTEAD OF CONTAINING THE DATA VALUE. IN THE CASE ! 3475: # OF A NATURAL VARIABLE, THE VRGET AND VRSTO FIELDS ! 3476: # CONTAIN =B$VRA AND =B$VRV TO ACTIVATE THE CHECK. ! 3477: # ! 3478: # TRTYP IS SET TO TRTAC ! 3479: # TRNXT POINTS TO NEXT TRBLK OR TRVAL HAS VARIABLE VAL ! 3480: # TRTAG IS THE TRACE TAG (0 IF NONE) ! 3481: # TRFNC IS THE TRACE FUNCTION VRBLK PTR (0 IF NONE) ! 3482: # ! 3483: # VARIABLE VALUE TRACE ASSOCIATION ! 3484: # ! 3485: # THE VALUE FIELD OF THE VARIABLE POINTS TO A TRBLK ! 3486: # INSTEAD OF CONTAINING THE DATA VALUE. IN THE CASE ! 3487: # OF A NATURAL VARIABLE, THE VRGET AND VRSTO FIELDS ! 3488: # CONTAIN =B$VRA AND =B$VRV TO ACTIVATE THE CHECK. ! 3489: # ! 3490: # TRTYP IS SET TO TRTVL ! 3491: # TRNXT POINTS TO NEXT TRBLK OR TRVAL HAS VARIABLE VAL ! 3492: # TRTAG IS THE TRACE TAG (0 IF NONE) ! 3493: # TRFNC IS THE TRACE FUNCTION VRBLK PTR (0 IF NONE) ! 3494: #page ! 3495: # TRAP BLOCK (CONTINUED) ! 3496: # ! 3497: # VARIABLE OUTPUT ASSOCIATION ! 3498: # ! 3499: # THE VALUE FIELD OF THE VARIABLE POINTS TO A TRBLK ! 3500: # INSTEAD OF CONTAINING THE DATA VALUE. IN THE CASE ! 3501: # OF A NATURAL VARIABLE, THE VRGET AND VRSTO FIELDS ! 3502: # CONTAIN =B$VRA AND =B$VRV TO ACTIVATE THE CHECK. ! 3503: # ! 3504: # TRTYP IS SET TO TRTOU ! 3505: # TRNXT POINTS TO NEXT TRBLK OR TRVAL HAS VARIABLE VAL ! 3506: # TRTER IS A POINTER TO SVBLK IF ASSOCIATION IS ! 3507: # FOR OUTPUT, TERMINAL, ELSE IT IS NULL. ! 3508: # TRTRF POINTS TO THE TRAP BLOCK WHICH IN TURN POINTS ! 3509: # TO AN FCBLK USED FOR I/O ASSOCIATION. ! 3510: # TRFPT IS THE FCBLK PTR RETURNED BY SYSIO. ! 3511: # ! 3512: # FUNCTION CALL TRACE ! 3513: # ! 3514: # THE PFCTR FIELD OF THE CORRESPONDING PFBLK IS SET ! 3515: # TO POINT TO A TRBLK. ! 3516: # ! 3517: # TRTYP IS SET TO TRTIN ! 3518: # TRNXT IS ZERO ! 3519: # TRTAG IS THE TRACE TAG (0 IF NONE) ! 3520: # TRFNC IS THE TRACE FUNCTION VRBLK PTR (0 IF NONE) ! 3521: # ! 3522: # FUNCTION RETURN TRACE ! 3523: # ! 3524: # THE PFRTR FIELD OF THE CORRESPONDING PFBLK IS SET ! 3525: # TO POINT TO A TRBLK ! 3526: # ! 3527: # TRTYP IS SET TO TRTIN ! 3528: # TRNXT IS ZERO ! 3529: # TRTAG IS THE TRACE TAG (0 IF NONE) ! 3530: # TRFNC IS THE TRACE FUNCTION VRBLK PTR (0 IF NONE) ! 3531: # ! 3532: # LABEL TRACE ! 3533: # ! 3534: # THE VRLBL OF THE VRBLK FOR THE LABEL IS ! 3535: # CHANGED TO POINT TO A TRBLK AND THE VRTRA FIELD IS ! 3536: # SET TO B$VRT TO ACTIVATE THE CHECK. ! 3537: # ! 3538: # TRTYP IS SET TO TRTIN ! 3539: # TRLBL POINTS TO THE ACTUAL LABEL (CDBLK) VALUE ! 3540: # TRTAG IS THE TRACE TAG (0 IF NONE) ! 3541: # TRFNC IS THE TRACE FUNCTION VRBLK PTR (0 IF NONE) ! 3542: #page ! 3543: # ! 3544: # TRAP BLOCK (CONTINUED) ! 3545: # ! 3546: # KEYWORD TRACE ! 3547: # ! 3548: # KEYWORDS WHICH CAN BE TRACED POSSESS A UNIQUE ! 3549: # LOCATION WHICH IS ZERO IF THERE IS NO TRACE AND ! 3550: # POINTS TO A TRBLK IF THERE IS A TRACE. THE LOCATIONS ! 3551: # ARE AS FOLLOWS. ! 3552: # ! 3553: # R$ERT ERRTYPE ! 3554: # R$FNC FNCLEVEL ! 3555: # R$STC STCOUNT ! 3556: # ! 3557: # THE FORMAT OF THE TRBLK IS AS FOLLOWS. ! 3558: # ! 3559: # TRTYP IS SET TO TRTIN ! 3560: # TRKVR IS A POINTER TO THE VRBLK FOR THE KEYWORD ! 3561: # TRTAG IS THE TRACE TAG (0 IF NONE) ! 3562: # TRFNC IS THE TRACE FUNCTION VRBLK PTR (0 IF NONE) ! 3563: # ! 3564: # INPUT/OUTPUT FILE ARG1 TRAP BLOCK ! 3565: # ! 3566: # THE VALUE FIELD OF THE VARIABLE POINTS TO A TRBLK ! 3567: # INSTEAD OF CONTAINING THE DATA VALUE. IN THE CASE OF ! 3568: # A NATURAL VARIABLE, THE VRGET AND VRSTO FIELDS ! 3569: # CONTAIN =B$VRA AND =B$VRV. THIS TRAP BLOCK IS USED ! 3570: # TO HOLD A POINTER TO THE FCBLK WHICH AN ! 3571: # IMPLEMENTATION MAY REQUEST TO HOLD INFORMATION ! 3572: # ABOUT A FILE. ! 3573: # ! 3574: # TRTYP IS SET TO TRTFC ! 3575: # TRNEXT POINTS TO NEXT TRBLK OR TRVAL IS VARIABLE VAL ! 3576: # TRFNM IS 0 ! 3577: # TRFPT IS THE FCBLK POINTER. ! 3578: # ! 3579: # NOTE THAT WHEN MULTIPLE TRAPS ARE SET ON A VARIABLE ! 3580: # THE ORDER IS IN ASCENDING VALUE OF TRTYP FIELD. ! 3581: # ! 3582: # INPUT ASSOCIATION (IF PRESENT) ! 3583: # ACCESS TRACE (IF PRESENT) ! 3584: # VALUE TRACE (IF PRESENT) ! 3585: # OUTPUT ASSOCIATION (IF PRESENT) ! 3586: # ! 3587: # THE ACTUAL VALUE OF THE VARIABLE IS STORED IN THE TRVAL ! 3588: # FIELD OF THE LAST TRBLK ON THE CHAIN. ! 3589: # ! 3590: # THIS IMPLEMENTATION DOES NOT PERMIT TRACE OR I/O ! 3591: # ASSOCIATIONS TO ANY OF THE PSEUDO-VARIABLES. ! 3592: #page ! 3593: # ! 3594: # VECTOR BLOCK (VCBLK) ! 3595: # ! 3596: # A VCBLK IS USED TO REPRESENT AN ARRAY VALUE WHICH HAS ! 3597: # ONE DIMENSION WHOSE LOWER BOUND IS ONE. ALL OTHER ARRAYS ! 3598: # ARE REPRESENTED BY ARBLKS. A VCBLK IS CREATED BY THE ! 3599: # SYSTEM FUNCTION ARRAY (S$ARR) WHEN PASSED AN INTEGER ARG. ! 3600: # ! 3601: # +------------------------------------+ ! 3602: # I VCTYP I ! 3603: # +------------------------------------+ ! 3604: # I IDVAL I ! 3605: # +------------------------------------+ ! 3606: # I VCLEN I ! 3607: # +------------------------------------+ ! 3608: # I VCVLS I ! 3609: # +------------------------------------+ ! 3610: # ! 3611: .set vctyp,0 # pointer to dummy routine b$vct ! 3612: .set vclen,offs2 # length of vcblk in bytes ! 3613: .set vcvls,offs3 # start of vector values ! 3614: .set vcsi$,vcvls # size of standard fields in vcblk ! 3615: .set vcvlb,vcvls-1 # offset one word behind vcvls ! 3616: .set vctbd,tbsi$-vcsi$# difference in sizes - see prtvl ! 3617: # ! 3618: # VCVLS ARE EITHER DATA POINTERS OR TRBLK POINTERS ! 3619: # ! 3620: # THE DIMENSION CAN BE DEDUCED FROM VCLEN. ! 3621: #page ! 3622: # ! 3623: # VARIABLE BLOCK (VRBLK) ! 3624: # ! 3625: # A VARIABLE BLOCK IS BUILT IN THE STATIC MEMORY AREA ! 3626: # FOR EVERY VARIABLE REFERENCED OR CREATED BY A PROGRAM. ! 3627: # ! 3628: # NOTE THAT SINCE THESE BLOCKS ONLY OCCUR IN THE STATIC ! 3629: # REGION, IT IS PERMISSIBLE TO POINT TO ANY WORD IN ! 3630: # THE BLOCK AND THIS IS USED TO PROVIDE THREE DISTINCT ! 3631: # ACCESS POINTS FROM THE GENERATED CODE AS FOLLOWS. ! 3632: # ! 3633: # 1) POINT TO VRGET (FIRST WORD OF VRBLK) TO LOAD THE ! 3634: # VALUE OF THE VARIABLE ONTO THE MAIN STACK. ! 3635: # ! 3636: # 2) POINT TO VRSTO (SECOND WORD OF VRBLK) TO STORE THE ! 3637: # TOP STACK ELEMENT AS THE VALUE OF THE VARIABLE. ! 3638: # ! 3639: # 3) POINT TO VRTRA (FOURTH WORD OF VRBLK) TO JUMP TO ! 3640: # THE LABEL ASSOCIATED WITH THE VARIABLE NAME. ! 3641: # ! 3642: # +------------------------------------+ ! 3643: # I VRGET I ! 3644: # +------------------------------------+ ! 3645: # I VRSTO I ! 3646: # +------------------------------------+ ! 3647: # I VRVAL I ! 3648: # +------------------------------------+ ! 3649: # I VRTRA I ! 3650: # +------------------------------------+ ! 3651: # I VRLBL I ! 3652: # +------------------------------------+ ! 3653: # I VRFNC I ! 3654: # +------------------------------------+ ! 3655: # I VRNXT I ! 3656: # +------------------------------------+ ! 3657: # I VRLEN I ! 3658: # +------------------------------------+ ! 3659: # / / ! 3660: # / VRCHS = VRSVP / ! 3661: # / / ! 3662: # +------------------------------------+ ! 3663: #page ! 3664: # ! 3665: # VARIABLE BLOCK (CONTINUED) ! 3666: # ! 3667: .set vrget,0 # pointer to routine to load value ! 3668: .set vrsto,vrget+1 # pointer to routine to store value ! 3669: .set vrval,vrsto+1 # variable value ! 3670: .set vrvlo,vrval-vrsto# offset to value from store field ! 3671: .set vrtra,vrval+1 # pointer to routine to jump to label ! 3672: .set vrlbl,vrtra+1 # pointer to code for label ! 3673: .set vrlbo,vrlbl-vrtra# offset to label from transfer field ! 3674: .set vrfnc,vrlbl+1 # pointer to function block ! 3675: .set vrnxt,vrfnc+1 # pointer to next vrblk on hash chain ! 3676: .set vrlen,vrnxt+1 # length of name (or zero) ! 3677: .set vrchs,vrlen+1 # characters of name (vrlen gt 0) ! 3678: .set vrsvp,vrlen+1 # ptr to svblk (vrlen eq 0) ! 3679: .set vrsi$,vrchs+1 # number of standard fields in vrblk ! 3680: .set vrsof,vrlen-sclen# offset to dummy scblk for name ! 3681: .set vrsvo,vrsvp-vrsof# pseudo-offset to vrsvp field ! 3682: # ! 3683: # VRGET = B$VRL IF NOT INPUT ASSOCIATED OR ACCESS TRACED ! 3684: # VRGET = B$VRA IF INPUT ASSOCIATED OR ACCESS TRACED ! 3685: # ! 3686: # VRSTO = B$VRS IF NOT OUTPUT ASSOCIATED OR VALUE TRACED ! 3687: # VRSTO = B$VRV IF OUTPUT ASSOCIATED OR VALUE TRACED ! 3688: # VRSTO = B$VRE IF VALUE IS PROTECTED PATTERN VALUE ! 3689: # ! 3690: # VRVAL POINTS TO THE APPROPRIATE VALUE UNLESS THE ! 3691: # VARIABLE IS I/O/TRACE ASSOCIATED IN WHICH CASE, VRVAL ! 3692: # POINTS TO AN APPROPRIATE TRBLK (TRAP BLOCK) CHAIN. ! 3693: # ! 3694: # VRTRA = B$VRG IF THE LABEL IS NOT TRACED ! 3695: # VRTRA = B$VRT IF THE LABEL IS TRACED ! 3696: # ! 3697: # VRLBL POINTS TO A CDBLK IF THERE IS A LABEL ! 3698: # VRLBL POINTS TO THE SVBLK SVLBL FIELD FOR A SYSTEM LABEL ! 3699: # VRLBL POINTS TO STNDL FOR AN UNDEFINED LABEL ! 3700: # VRLBL POINTS TO A TRBLK IF THE LABEL IS TRACED ! 3701: # ! 3702: # VRFNC POINTS TO A FFBLK FOR A FIELD FUNCTION ! 3703: # VRFNC POINTS TO A DFBLK FOR A DATATYPE FUNCTION ! 3704: # VRFNC POINTS TO A PFBLK FOR A PROGRAM DEFINED FUNCTION ! 3705: # VRFNC POINTS TO A EFBLK FOR AN EXTERNAL LOADED FUNCTION ! 3706: # VRFNC POINTS TO SVFNC (SVBLK) FOR A SYSTEM FUNCTION ! 3707: # VRFNC POINTS TO STNDF IF THE FUNCTION IS UNDEFINED ! 3708: # ! 3709: # VRNXT POINTS TO THE NEXT VRBLK ON THIS CHAIN UNLESS ! 3710: # THIS IS THE END OF THE CHAIN IN WHICH CASE IT IS ZERO. ! 3711: # ! 3712: # VRLEN IS THE NAME LENGTH FOR A NON-SYSTEM VARIABLE. ! 3713: # VRLEN IS ZERO FOR A SYSTEM VARIABLE. ! 3714: # ! 3715: # VRCHS IS THE NAME (LJRZ) IF VRLEN IS NON-ZERO. ! 3716: # VRSVP IS A PTR TO THE SVBLK IF VRLEN IS ZERO. ! 3717: #page ! 3718: # ! 3719: # FORMAT OF A NON-RELOCATABLE EXTERNAL BLOCK (XNBLK) ! 3720: # ! 3721: # AN XNBLK IS A BLOCK REPRESENTING AN UNKNOWN (EXTERNAL) ! 3722: # DATA VALUE. THE BLOCK CONTAINS NO POINTERS TO OTHER ! 3723: # RELOCATABLE BLOCKS. AN XNBLK IS USED BY EXTERNAL FUNCTION ! 3724: # PROCESSING OR POSSIBLY FOR SYSTEM I/O ROUTINES ETC. ! 3725: # THE MACRO-SYSTEM ITSELF DOES NOT USE XNBLKS. ! 3726: # THIS TYPE OF BLOCK MAY BE USED AS A FILE CONTROL BLOCK. ! 3727: # SEE SYSFC,SYSIN,SYSOU,S$INP,S$OUP FOR DETAILS. ! 3728: # ! 3729: # +------------------------------------+ ! 3730: # I XNTYP I ! 3731: # +------------------------------------+ ! 3732: # I XNLEN I ! 3733: # +------------------------------------+ ! 3734: # / / ! 3735: # / XNDTA / ! 3736: # / / ! 3737: # +------------------------------------+ ! 3738: # ! 3739: .set xntyp,0 # pointer to dummy routine b$xnt ! 3740: .set xnlen,xntyp+1 # length of xnblk in bytes ! 3741: .set xndta,xnlen+1 # data words ! 3742: .set xnsi$,xndta # size of standard fields in xnblk ! 3743: # ! 3744: # NOTE THAT THE TERM NON-RELOCATABLE REFERS TO THE CONTENTS ! 3745: # AND NOT THE BLOCK ITSELF. AN XNBLK CAN BE MOVED AROUND IF ! 3746: # IT IS BUILT IN THE DYNAMIC MEMORY AREA. ! 3747: #page ! 3748: # ! 3749: # RELOCATABLE EXTERNAL BLOCK (XRBLK) ! 3750: # ! 3751: # AN XRBLK IS A BLOCK REPRESENTING AN UNKNOWN (EXTERNAL) ! 3752: # DATA VALUE. THE DATA AREA IN THIS BLOCK CONSISTS ONLY ! 3753: # OF ADDRESS VALUES AND ANY ADDRESSES POINTING INTO THE ! 3754: # DYNAMIC MEMORY AREA MUST POINT TO THE START OF OTHER ! 3755: # DATA BLOCKS. SEE ALSO DESCRIPTION OF XNBLK. ! 3756: # THIS TYPE OF BLOCK MAY BE USED AS A FILE CONTROL BLOCK. ! 3757: # SEE SYSFC,SYSIN,SYSOU,S$INP,S$OUP FOR DETAILS. ! 3758: # ! 3759: # +------------------------------------+ ! 3760: # I XRTYP I ! 3761: # +------------------------------------+ ! 3762: # I XRLEN I ! 3763: # +------------------------------------+ ! 3764: # / / ! 3765: # / XRPTR / ! 3766: # / / ! 3767: # +------------------------------------+ ! 3768: # ! 3769: .set xrtyp,0 # pointer to dummy routine b$xrt ! 3770: .set xrlen,xrtyp+1 # length of xrblk in bytes ! 3771: .set xrptr,xrlen+1 # start of address pointers ! 3772: .set xrsi$,xrptr # size of standard fields in xrblk ! 3773: #page ! 3774: # ! 3775: # S$CNV (CONVERT) FUNCTION SWITCH CONSTANTS. THE VALUES ! 3776: # ARE TIED TO THE ORDER OF THE ENTRIES IN THE SVCTB TABLE ! 3777: # AND HENCE TO THE BRANCH TABLE IN S$CNV. ! 3778: # ! 3779: .set cnvst,8 # max standard type code for convert ! 3780: .set cnvrt,cnvst+1 # convert code for reals ! 3781: .set cnvbt,cnvrt+1 # convert code for buffer ! 3782: .set cnvtt,cnvbt+1 # bsw code for convert ! 3783: # ! 3784: # INPUT IMAGE LENGTH ! 3785: # ! 3786: .set iniln,132 # default image length for compiler ! 3787: .set inils,80 # image length if -sequ in effect ! 3788: # ! 3789: .set ionmb,2 # name base used for iochn in sysio ! 3790: .set ionmo,4 # name offset used for iochn in sysio ! 3791: # ! 3792: # IN GENERAL, MEANINGFUL MNEMONICS SHOULD BE USED FOR ! 3793: # OFFSETS. HOWEVER FOR SMALL INTEGERS USED OFTEN IN ! 3794: # LITERALS THE FOLLOWING GENERAL DEFINITIONS ARE PROVIDED. ! 3795: # ! 3796: .set num01,1 ! 3797: .set num02,2 ! 3798: .set num03,3 ! 3799: .set num04,4 ! 3800: .set num05,5 ! 3801: .set num06,6 ! 3802: .set num07,7 ! 3803: .set num08,8 ! 3804: .set num09,9 ! 3805: .set num10,10 ! 3806: .set nini8,998 ! 3807: .set nini9,999 ! 3808: .set thsnd,1000 ! 3809: #page ! 3810: # ! 3811: # NUMBERS OF UNDEFINED SPITBOL OPERATORS ! 3812: # ! 3813: .set opbun,5 # no. of binary undefined ops ! 3814: .set opuun,6 # no of unary undefined ops ! 3815: # ! 3816: # OFFSETS USED IN PRTSN, PRTMI AND ACESS ! 3817: # ! 3818: .set prsnf,13 # offset used in prtsn ! 3819: .set prtmf,15 # offset to col 15 (prtmi) ! 3820: .set rilen,120 # buffer length for sysri ! 3821: # ! 3822: # CODES FOR STAGES OF PROCESSING ! 3823: # ! 3824: .set stgic,0 # initial compile ! 3825: .set stgxc,stgic+1 # execution compile (code) ! 3826: .set stgev,stgxc+1 # expression eval during execution ! 3827: .set stgxt,stgev+1 # execution time ! 3828: .set stgce,stgxt+1 # initial compile after end line ! 3829: .set stgxe,stgce+1 # exec. compile after end line ! 3830: .set stgnd,stgce-stgic# difference in stage after end ! 3831: .set stgee,stgxe+1 # eval evaluating expression ! 3832: .set stgno,stgee+1 # number of codes ! 3833: #page ! 3834: # ! 3835: # ! 3836: # STATEMENT NUMBER PAD COUNT FOR LISTR ! 3837: # ! 3838: .set stnpd,8 # statement no. pad count ! 3839: # ! 3840: # SYNTAX TYPE CODES ! 3841: # ! 3842: # THESE CODES ARE RETURNED FROM THE SCANE PROCEDURE. ! 3843: # ! 3844: # THEY ARE SPACED 3 APART FOR THE BENEFIT OF EXPAN. ! 3845: # ! 3846: .set t$uop,0 # unary operator ! 3847: .set t$lpr,t$uop+3 # left paren ! 3848: .set t$lbr,t$lpr+3 # left bracket ! 3849: .set t$cma,t$lbr+3 # comma ! 3850: .set t$fnc,t$cma+3 # function call ! 3851: .set t$var,t$fnc+3 # variable ! 3852: .set t$con,t$var+3 # constant ! 3853: .set t$bop,t$con+3 # binary operator ! 3854: .set t$rpr,t$bop+3 # right paren ! 3855: .set t$rbr,t$rpr+3 # right bracket ! 3856: .set t$col,t$rbr+3 # colon ! 3857: .set t$smc,t$col+3 # semi-colon ! 3858: # ! 3859: # THE FOLLOWING DEFINITIONS ARE USED ONLY IN THE GOTO FIELD ! 3860: # ! 3861: .set t$fgo,t$smc+1 # failure goto ! 3862: .set t$sgo,t$fgo+1 # success goto ! 3863: # ! 3864: # THE ABOVE CODES ARE GROUPED SO THAT CODES FOR ELEMENTS ! 3865: # WHICH CAN LEGITIMATELY IMMEDIATELY PRECEDE A UNARY ! 3866: # OPERATOR COME FIRST TO FACILITATE OPERATOR SYNTAX CHECK. ! 3867: # ! 3868: .set t$uok,t$fnc # last code ok before unary operator ! 3869: #page ! 3870: # ! 3871: # DEFINITIONS OF VALUES FOR EXPAN JUMP TABLE ! 3872: # ! 3873: .set t$uo0,t$uop+0 # unary operator, state zero ! 3874: .set t$uo1,t$uop+1 # unary operator, state one ! 3875: .set t$uo2,t$uop+2 # unary operator, state two ! 3876: .set t$lp0,t$lpr+0 # left paren, state zero ! 3877: .set t$lp1,t$lpr+1 # left paren, state one ! 3878: .set t$lp2,t$lpr+2 # left paren, state two ! 3879: .set t$lb0,t$lbr+0 # left bracket, state zero ! 3880: .set t$lb1,t$lbr+1 # left bracket, state one ! 3881: .set t$lb2,t$lbr+2 # left bracket, state two ! 3882: .set t$cm0,t$cma+0 # comma, state zero ! 3883: .set t$cm1,t$cma+1 # comma, state one ! 3884: .set t$cm2,t$cma+2 # comma, state two ! 3885: .set t$fn0,t$fnc+0 # function call, state zero ! 3886: .set t$fn1,t$fnc+1 # function call, state one ! 3887: .set t$fn2,t$fnc+2 # function call, state two ! 3888: .set t$va0,t$var+0 # variable, state zero ! 3889: .set t$va1,t$var+1 # variable, state one ! 3890: .set t$va2,t$var+2 # variable, state two ! 3891: .set t$co0,t$con+0 # constant, state zero ! 3892: .set t$co1,t$con+1 # constant, state one ! 3893: .set t$co2,t$con+2 # constant, state two ! 3894: .set t$bo0,t$bop+0 # binary operator, state zero ! 3895: .set t$bo1,t$bop+1 # binary operator, state one ! 3896: .set t$bo2,t$bop+2 # binary operator, state two ! 3897: .set t$rp0,t$rpr+0 # right paren, state zero ! 3898: .set t$rp1,t$rpr+1 # right paren, state one ! 3899: .set t$rp2,t$rpr+2 # right paren, state two ! 3900: .set t$rb0,t$rbr+0 # right bracket, state zero ! 3901: .set t$rb1,t$rbr+1 # right bracket, state one ! 3902: .set t$rb2,t$rbr+2 # right bracket, state two ! 3903: .set t$cl0,t$col+0 # colon, state zero ! 3904: .set t$cl1,t$col+1 # colon, state one ! 3905: .set t$cl2,t$col+2 # colon, state two ! 3906: .set t$sm0,t$smc+0 # semicolon, state zero ! 3907: .set t$sm1,t$smc+1 # semicolon, state one ! 3908: .set t$sm2,t$smc+2 # semicolon, state two ! 3909: # ! 3910: .set t$nes,t$sm2+1 # number of entries in branch table ! 3911: #page ! 3912: # ! 3913: # DEFINITION OF OFFSETS USED IN CONTROL CARD PROCESSING ! 3914: # ! 3915: .set cc$ca,0 # -case ! 3916: .set cc$do,cc$ca+1 # -double ! 3917: .set cc$du,cc$do+1 # -dump ! 3918: .set cc$ej,cc$du+1 # -eject ! 3919: .set cc$er,cc$ej+1 # -errors ! 3920: .set cc$ex,cc$er+1 # -execute ! 3921: .set cc$fa,cc$ex+1 # -fail ! 3922: .set cc$li,cc$fa+1 # -list ! 3923: .set cc$nr,cc$li+1 # -noerrors ! 3924: .set cc$nx,cc$nr+1 # -noexecute ! 3925: .set cc$nf,cc$nx+1 # -nofail ! 3926: .set cc$nl,cc$nf+1 # -nolist ! 3927: .set cc$no,cc$nl+1 # -noopt ! 3928: .set cc$np,cc$no+1 # -noprint ! 3929: .set cc$op,cc$np+1 # -optimise ! 3930: .set cc$pr,cc$op+1 # -print ! 3931: .set cc$si,cc$pr+1 # -single ! 3932: .set cc$sp,cc$si+1 # -space ! 3933: .set cc$st,cc$sp+1 # -stitl ! 3934: .set cc$ti,cc$st+1 # -title ! 3935: .set cc$tr,cc$ti+1 # -trace ! 3936: .set cc$nc,cc$tr+1 # number of control cards ! 3937: .set ccnoc,4 # no. of chars included in match ! 3938: .set ccofs,7 # offset to start of title/subtitle ! 3939: #page ! 3940: # ! 3941: # DEFINITIONS OF STACK OFFSETS USED IN CMPIL PROCEDURE ! 3942: # ! 3943: # SEE DESCRIPTION AT START OF CMPIL PROCEDURE FOR DETAILS ! 3944: # OF USE OF THESE LOCATIONS ON THE STACK. ! 3945: # ! 3946: .set cmstm,0 # tree for statement body ! 3947: .set cmsgo,cmstm+1 # tree for success goto ! 3948: .set cmfgo,cmsgo+1 # tree for fail goto ! 3949: .set cmcgo,cmfgo+1 # conditional goto flag ! 3950: .set cmpcd,cmcgo+1 # previous cdblk pointer ! 3951: .set cmffp,cmpcd+1 # failure fill in flag for previous ! 3952: .set cmffc,cmffp+1 # failure fill in flag for current ! 3953: .set cmsop,cmffc+1 # success fill in offset for previous ! 3954: .set cmsoc,cmsop+1 # success fill in offset for current ! 3955: .set cmlbl,cmsoc+1 # ptr to vrblk for current label ! 3956: .set cmtra,cmlbl+1 # ptr to entry cdblk ! 3957: # ! 3958: .set cmnen,cmtra+1 # count of stack entries for cmpil ! 3959: # ! 3960: # A FEW CONSTANTS USED BY THE PROFILER ! 3961: .set pfpd1,8 # pad positions ... ! 3962: .set pfpd2,20 # ... for profile ... ! 3963: .set pfpd3,32 # ... printout ! 3964: .set pf$i2,cfp$i+cfp$i# size of table entry (2 ints) ! 3965: # ! 3966: #title s p i t b o l -- constant section ! 3967: # ! 3968: # THIS SECTION CONSISTS ENTIRELY OF ASSEMBLED CONSTANTS. ! 3969: # ! 3970: # ALL LABEL NAMES ARE FIVE LETTERS. THE ORDER IS ! 3971: # APPROXIMATELY ALPHABETICAL, BUT IN SOME CASES (ALWAYS ! 3972: # DOCUMENTED), CONSTANTS MUST BE PLACED IN SOME SPECIAL ! 3973: # ORDER WHICH MUST NOT BE DISTURBED. ! 3974: # ! 3975: # IT MUST ALSO BE REMEMBERED THAT THERE IS A REQUIREMENT ! 3976: # FOR NO FORWARD REFERENCES WHICH ALSO DISTURBS THE ! 3977: # ALPHABETICAL ORDER IN SOME CASES. ! 3978: # ! 3979: .data 0 ! 3980: #sec # start of constant section ! 3981: # ! 3982: # FREE STORE PERCENTAGE (USED BY ALLOC) ! 3983: # ! 3984: alfsp: .long e$fsp # free store percentage ! 3985: # ! 3986: # BIT CONSTANTS FOR GENERAL USE ! 3987: # ! 3988: bits0: .long 0 # all zero bits ! 3989: bits1: .long 1 # one bit in low order position ! 3990: bits2: .long 2 # bit in position 2 ! 3991: bits3: .long 4 # bit in position 3 ! 3992: bits4: .long 8 # bit in position 4 ! 3993: bits5: .long 16 # bit in position 5 ! 3994: bits6: .long 32 # bit in position 6 ! 3995: bits7: .long 64 # bit in position 7 ! 3996: bits8: .long 128 # bit in position 8 ! 3997: bits9: .long 256 # bit in position 9 ! 3998: bit10: .long 512 # bit in position 10 ! 3999: bitsm: .long cfp$m # mask for max integer ! 4000: # ! 4001: # BIT CONSTANTS FOR SVBLK (SVBIT FIELD) TESTS ! 4002: # ! 4003: btfnc: .long svfnc # bit to test for function ! 4004: btknm: .long svknm # bit to test for keyword number ! 4005: btlbl: .long svlbl # bit to test for label ! 4006: btffc: .long svffc # bit to test for fast call ! 4007: btckw: .long svckw # bit to test for constant keyword ! 4008: btprd: .long svprd # bit to test for predicate function ! 4009: btpre: .long svpre # bit to test for preevaluation ! 4010: btval: .long svval # bit to test for value ! 4011: #page ! 4012: # ! 4013: # LIST OF NAMES USED FOR CONTROL CARD PROCESSING ! 4014: # ! 4015: ccnms: .ascii "CASE" ! 4016: .align 2 ! 4017: .ascii "DOUB" ! 4018: .align 2 ! 4019: .ascii "DUMP" ! 4020: .align 2 ! 4021: .ascii "EJEC" ! 4022: .align 2 ! 4023: .ascii "ERRO" ! 4024: .align 2 ! 4025: .ascii "EXEC" ! 4026: .align 2 ! 4027: .ascii "FAIL" ! 4028: .align 2 ! 4029: .ascii "LIST" ! 4030: .align 2 ! 4031: .ascii "NOER" ! 4032: .align 2 ! 4033: .ascii "NOEX" ! 4034: .align 2 ! 4035: .ascii "NOFA" ! 4036: .align 2 ! 4037: .ascii "NOLI" ! 4038: .align 2 ! 4039: .ascii "NOOP" ! 4040: .align 2 ! 4041: .ascii "NOPR" ! 4042: .align 2 ! 4043: .ascii "OPTI" ! 4044: .align 2 ! 4045: .ascii "PRIN" ! 4046: .align 2 ! 4047: .ascii "SING" ! 4048: .align 2 ! 4049: .ascii "SPAC" ! 4050: .align 2 ! 4051: .ascii "STIT" ! 4052: .align 2 ! 4053: .ascii "TITL" ! 4054: .align 2 ! 4055: .ascii "TRAC" ! 4056: .align 2 ! 4057: # ! 4058: # HEADER MESSAGES FOR DUMPR PROCEDURE (SCBLK FORMAT) ! 4059: # ! 4060: dmhdk: .long b$scl # dump of keyword values ! 4061: .long 22 ! 4062: .ascii "DUMP OF KEYWORD VALUES" ! 4063: .align 2 ! 4064: # ! 4065: dmhdv: .long b$scl # dump of natural variables ! 4066: .long 25 ! 4067: .ascii "DUMP OF NATURAL VARIABLES" ! 4068: .align 2 ! 4069: #page ! 4070: # ! 4071: # MESSAGE TEXT FOR COMPILATION STATISTICS ! 4072: # ! 4073: encm1: .long b$scl ! 4074: .long 10 ! 4075: .ascii "STORE USED" ! 4076: .align 2 ! 4077: # ! 4078: encm2: .long b$scl ! 4079: .long 10 ! 4080: .ascii "STORE LEFT" ! 4081: .align 2 ! 4082: # ! 4083: encm3: .long b$scl ! 4084: .long 11 ! 4085: .ascii "COMP ERRORS" ! 4086: .align 2 ! 4087: # ! 4088: encm4: .long b$scl ! 4089: .long 14 ! 4090: .ascii "COMP TIME-MSEC" ! 4091: .align 2 ! 4092: # ! 4093: encm5: .long b$scl # execution suppressed ! 4094: .long 20 ! 4095: .ascii "EXECUTION SUPPRESSED" ! 4096: .align 2 ! 4097: # ! 4098: # STRING CONSTANT FOR ABNORMAL END ! 4099: # ! 4100: endab: .long b$scl ! 4101: .long 12 ! 4102: .ascii "ABNORMAL END" ! 4103: .align 2 ! 4104: #page ! 4105: # ! 4106: # MEMORY OVERFLOW DURING INITIALISATION ! 4107: # ! 4108: endmo: .long b$scl ! 4109: endml: .long 15 ! 4110: .ascii "MEMORY OVERFLOW" ! 4111: .align 2 ! 4112: # ! 4113: # STRING CONSTANT FOR MESSAGE ISSUED BY L$END ! 4114: # ! 4115: endms: .long b$scl ! 4116: .long 10 ! 4117: .ascii "NORMAL END" ! 4118: .align 2 ! 4119: # ! 4120: # FAIL MESSAGE FOR STACK FAIL SECTION ! 4121: # ! 4122: endso: .long b$scl # stack overflow in garbage collector ! 4123: .long 36 ! 4124: .ascii "STACK OVERFLOW IN GARBAGE COLLECTION" ! 4125: .align 2 ! 4126: # ! 4127: # STRING CONSTANT FOR TIME UP ! 4128: # ! 4129: endtu: .long b$scl ! 4130: .long 15 ! 4131: .ascii "ERROR - TIME UP" ! 4132: .align 2 ! 4133: #page ! 4134: # ! 4135: # STRING CONSTANT FOR ERROR MESSAGE (ERROR SECTION) ! 4136: # ! 4137: ermms: .long b$scl # error ! 4138: .long 5 ! 4139: .ascii "ERROR" ! 4140: .align 2 ! 4141: # ! 4142: ermns: .long b$scl # string / -- / ! 4143: .long 4 ! 4144: .ascii " -- " ! 4145: .align 2 ! 4146: # ! 4147: # STRING CONSTANT FOR PAGE NUMBERING ! 4148: # ! 4149: lstms: .long b$scl # page ! 4150: .long 5 ! 4151: .ascii "PAGE " ! 4152: .align 2 ! 4153: # ! 4154: # LISTING HEADER MESSAGE ! 4155: # ! 4156: headr: .long b$scl ! 4157: .long 25 ! 4158: .ascii "MACRO SPITBOL VERSION 3.5" ! 4159: .align 2 ! 4160: # ! 4161: headv: .long b$scl # for exit() version no. check ! 4162: .long 3 ! 4163: .ascii "3.5" ! 4164: .align 2 ! 4165: # ! 4166: # INTEGER CONSTANTS FOR GENERAL USE ! 4167: # ICBLD OPTIMISATION USES THE FIRST THREE. ! 4168: # ! 4169: int$r: .long b$icl ! 4170: intv0: .long 0 # 0 ! 4171: inton: .long b$icl ! 4172: intv1: .long 1 # 1 ! 4173: inttw: .long b$icl ! 4174: intv2: .long 2 # 2 ! 4175: intvt: .long 10 # 10 ! 4176: intvh: .long 100 # 100 ! 4177: intth: .long 1000 # 1000 ! 4178: # ! 4179: # TABLE USED IN ICBLD OPTIMISATION ! 4180: # ! 4181: intab: .long int$r # pointer to 0 ! 4182: .long inton # pointer to 1 ! 4183: .long inttw # pointer to 2 ! 4184: #page ! 4185: # ! 4186: # SPECIAL PATTERN NODES. THE FOLLOWING PATTERN NODES ! 4187: # CONSIST SIMPLY OF A PCODE POINTER, SEE MATCH ROUTINES ! 4188: # (P$XXX) FOR FULL DETAILS OF THEIR USE AND FORMAT). ! 4189: # ! 4190: ndabb: .long p$abb # arbno ! 4191: ndabd: .long p$abd # arbno ! 4192: ndarc: .long p$arc # arb ! 4193: ndexb: .long p$exb # expression ! 4194: ndfnb: .long p$fnb # fence() ! 4195: ndfnd: .long p$fnd # fence() ! 4196: ndexc: .long p$exc # expression ! 4197: ndimb: .long p$imb # immediate assignment ! 4198: ndimd: .long p$imd # immediate assignment ! 4199: ndnth: .long p$nth # pattern end (null pattern) ! 4200: ndpab: .long p$pab # pattern assignment ! 4201: ndpad: .long p$pad # pattern assignment ! 4202: nduna: .long p$una # anchor point movement ! 4203: # ! 4204: # KEYWORD CONSTANT PATTERN NODES. THE FOLLOWING NODES ARE ! 4205: # USED AS THE VALUES OF PATTERN KEYWORDS AND THE INITIAL ! 4206: # VALUES OF THE CORRESPONDING NATURAL VARIABLES. ALL ! 4207: # NODES ARE IN P0BLK FORMAT AND THE ORDER IS TIED TO THE ! 4208: # DEFINITIONS OF CORRESPONDING K$XXX SYMBOLS. ! 4209: # ! 4210: ndabo: .long p$abo # abort ! 4211: .long ndnth ! 4212: ndarb: .long p$arb # arb ! 4213: .long ndnth ! 4214: ndbal: .long p$bal # bal ! 4215: .long ndnth ! 4216: ndfal: .long p$fal # fail ! 4217: .long ndnth ! 4218: ndfen: .long p$fen # fence ! 4219: .long ndnth ! 4220: ndrem: .long p$rem # rem ! 4221: .long ndnth ! 4222: ndsuc: .long p$suc # succeed ! 4223: .long ndnth ! 4224: # ! 4225: # NULL STRING. ALL NULL VALUES POINT TO THIS STRING. THE ! 4226: # SVCHS FIELD CONTAINS A BLANK TO PROVIDE FOR EASY DEFAULT ! 4227: # PROCESSING IN TRACE, STOPTR, LPAD AND RPAD. ! 4228: # NULLW CONTAINS 10 BLANKS WHICH ENSURES AN ALL BLANK WORD ! 4229: # BUT FOR VERY EXCEPTIONAL MACHINES. ! 4230: # ! 4231: nulls: .long b$scl # null string value ! 4232: .long 0 # sclen = 0 ! 4233: nullw: .ascii " " ! 4234: .align 2 ! 4235: #page ! 4236: # ! 4237: # OPERATOR DOPE VECTORS (SEE DVBLK FORMAT) ! 4238: # ! 4239: opdvc: .long o$cnc # concatenation ! 4240: .long c$cnc ! 4241: .long llcnc ! 4242: .long rrcnc ! 4243: # ! 4244: # OPDVS IS USED WHEN SCANNING BELOW THE TOP LEVEL TO ! 4245: # INSURE THAT THE CONCATENATION WILL NOT BE LATER ! 4246: # MISTAKEN FOR PATTERN MATCHING ! 4247: # ! 4248: opdvp: .long o$cnc # concatenation - not pattern match ! 4249: .long c$cnp ! 4250: .long llcnc ! 4251: .long rrcnc ! 4252: # ! 4253: # NOTE THAT THE ORDER OF THE REMAINING ENTRIES IS TIED TO ! 4254: # THE ORDER OF THE CODING IN THE SCANE PROCEDURE. ! 4255: # ! 4256: opdvs: .long o$ass # assignment ! 4257: .long c$ass ! 4258: .long llass ! 4259: .long rrass ! 4260: # ! 4261: .long 6 # unary equal ! 4262: .long c$uuo ! 4263: .long lluno ! 4264: # ! 4265: .long o$pmv # pattern match ! 4266: .long c$pmt ! 4267: .long llpmt ! 4268: .long rrpmt ! 4269: # ! 4270: .long o$int # interrogation ! 4271: .long c$uvl ! 4272: .long lluno ! 4273: # ! 4274: .long 1 # binary ampersand ! 4275: .long c$ubo ! 4276: .long llamp ! 4277: .long rramp ! 4278: # ! 4279: .long o$kwv # keyword reference ! 4280: .long c$key ! 4281: .long lluno ! 4282: # ! 4283: .long o$alt # alternation ! 4284: .long c$alt ! 4285: .long llalt ! 4286: .long rralt ! 4287: #page ! 4288: # ! 4289: # OPERATOR DOPE VECTORS (CONTINUED) ! 4290: # ! 4291: .long 5 # unary vertical bar ! 4292: .long c$uuo ! 4293: .long lluno ! 4294: # ! 4295: .long 0 # binary at ! 4296: .long c$ubo ! 4297: .long llats ! 4298: .long rrats ! 4299: # ! 4300: .long o$cas # cursor assignment ! 4301: .long c$unm ! 4302: .long lluno ! 4303: # ! 4304: .long 2 # binary number sign ! 4305: .long c$ubo ! 4306: .long llnum ! 4307: .long rrnum ! 4308: # ! 4309: .long 7 # unary number sign ! 4310: .long c$uuo ! 4311: .long lluno ! 4312: # ! 4313: .long o$dvd # division ! 4314: .long c$bvl ! 4315: .long lldvd ! 4316: .long rrdvd ! 4317: # ! 4318: .long 9 # unary slash ! 4319: .long c$uuo ! 4320: .long lluno ! 4321: # ! 4322: .long o$mlt # multiplication ! 4323: .long c$bvl ! 4324: .long llmlt ! 4325: .long rrmlt ! 4326: #page ! 4327: # ! 4328: # OPERATOR DOPE VECTORS (CONTINUED) ! 4329: # ! 4330: .long 0 # deferred expression ! 4331: .long c$def ! 4332: .long lluno ! 4333: # ! 4334: .long 3 # binary percent ! 4335: .long c$ubo ! 4336: .long llpct ! 4337: .long rrpct ! 4338: # ! 4339: .long 8 # unary percent ! 4340: .long c$uuo ! 4341: .long lluno ! 4342: # ! 4343: .long o$exp # exponentiation ! 4344: .long c$bvl ! 4345: .long llexp ! 4346: .long rrexp ! 4347: # ! 4348: .long 10 # unary exclamation ! 4349: .long c$uuo ! 4350: .long lluno ! 4351: # ! 4352: .long o$ima # immediate assignment ! 4353: .long c$bvn ! 4354: .long lldld ! 4355: .long rrdld ! 4356: # ! 4357: .long o$inv # indirection ! 4358: .long c$ind ! 4359: .long lluno ! 4360: # ! 4361: .long 4 # binary not ! 4362: .long c$ubo ! 4363: .long llnot ! 4364: .long rrnot ! 4365: # ! 4366: .long 0 # negation ! 4367: .long c$neg ! 4368: .long lluno ! 4369: #page ! 4370: # ! 4371: # OPERATOR DOPE VECTORS (CONTINUED) ! 4372: # ! 4373: .long o$sub # subtraction ! 4374: .long c$bvl ! 4375: .long llplm ! 4376: .long rrplm ! 4377: # ! 4378: .long o$com # complementation ! 4379: .long c$uvl ! 4380: .long lluno ! 4381: # ! 4382: .long o$add # addition ! 4383: .long c$bvl ! 4384: .long llplm ! 4385: .long rrplm ! 4386: # ! 4387: .long o$aff # affirmation ! 4388: .long c$uvl ! 4389: .long lluno ! 4390: # ! 4391: .long o$pas # pattern assignment ! 4392: .long c$bvn ! 4393: .long lldld ! 4394: .long rrdld ! 4395: # ! 4396: .long o$nam # name reference ! 4397: .long c$unm ! 4398: .long lluno ! 4399: # ! 4400: # SPECIAL DVS FOR GOTO OPERATORS (SEE PROCEDURE SCNGF) ! 4401: # ! 4402: opdvd: .long o$god # direct goto ! 4403: .long c$uvl ! 4404: .long lluno ! 4405: # ! 4406: opdvn: .long o$goc # complex normal goto ! 4407: .long c$unm ! 4408: .long lluno ! 4409: #page ! 4410: # ! 4411: # OPERATOR ENTRY ADDRESS POINTERS, USED IN CODE ! 4412: # ! 4413: oamn$: .long o$amn # array ref (multi-subs by value) ! 4414: oamv$: .long o$amv # array ref (multi-subs by value) ! 4415: oaon$: .long o$aon # array ref (one sub by name) ! 4416: oaov$: .long o$aov # array ref (one sub by value) ! 4417: ocer$: .long o$cer # compilation error ! 4418: ofex$: .long o$fex # failure in expression evaluation ! 4419: ofif$: .long o$fif # failure during goto evaluation ! 4420: ofnc$: .long o$fnc # function call (more than one arg) ! 4421: ofne$: .long o$fne # function name error ! 4422: ofns$: .long o$fns # function call (single argument) ! 4423: ogof$: .long o$gof # set goto failure trap ! 4424: oinn$: .long o$inn # indirection by name ! 4425: okwn$: .long o$kwn # keyword reference by name ! 4426: olex$: .long o$lex # load expression by name ! 4427: olpt$: .long o$lpt # load pattern ! 4428: olvn$: .long o$lvn # load variable name ! 4429: onta$: .long o$nta # negation, first entry ! 4430: ontb$: .long o$ntb # negation, second entry ! 4431: ontc$: .long o$ntc # negation, third entry ! 4432: opmn$: .long o$pmn # pattern match by name ! 4433: opms$: .long o$pms # pattern match (statement) ! 4434: opop$: .long o$pop # pop top stack item ! 4435: ornm$: .long o$rnm # return name from expression ! 4436: orpl$: .long o$rpl # pattern replacement ! 4437: orvl$: .long o$rvl # return value from expression ! 4438: osla$: .long o$sla # selection, first entry ! 4439: oslb$: .long o$slb # selection, second entry ! 4440: oslc$: .long o$slc # selection, third entry ! 4441: osld$: .long o$sld # selection, fourth entry ! 4442: ostp$: .long o$stp # stop execution ! 4443: ounf$: .long o$unf # unexpected failure ! 4444: #page ! 4445: # ! 4446: # TABLE OF NAMES OF UNDEFINED BINARY OPERATORS FOR OPSYN ! 4447: # ! 4448: opsnb: .long ch$at # at ! 4449: .long ch$am # ampersand ! 4450: .long ch$nm # number ! 4451: .long ch$pc # percent ! 4452: .long ch$nt # not ! 4453: # ! 4454: # TABLE OF NAMES OF UNDEFINED UNARY OPERATORS FOR OPSYN ! 4455: # ! 4456: opnsu: .long ch$br # vertical bar ! 4457: .long ch$eq # equal ! 4458: .long ch$nm # number ! 4459: .long ch$pc # percent ! 4460: .long ch$sl # slash ! 4461: .long ch$ex # exclamation ! 4462: # ! 4463: # ADDRESS CONST CONTAINING PROFILE TABLE ENTRY SIZE ! 4464: # ! 4465: pfi2a: .long pf$i2 ! 4466: # ! 4467: # PROFILER MESSAGE STRINGS ! 4468: # ! 4469: pfms1: .long b$scl ! 4470: .long 15 ! 4471: .ascii "PROGRAM PROFILE" ! 4472: .align 2 ! 4473: pfms2: .long b$scl ! 4474: .long 42 ! 4475: .ascii "STMT NUMBER OF -- EXECUTION TIME --" ! 4476: .align 2 ! 4477: pfms3: .long b$scl ! 4478: .long 47 ! 4479: .ascii "NUMBER EXECUTIONS TOTAL(MSEC) PER EXCN(MCSEC)" ! 4480: .align 2 ! 4481: # ! 4482: # ! 4483: # REAL CONSTANTS FOR GENERAL USE. NOTE THAT THE CONSTANTS ! 4484: # STARTING AT REAV1 FORM A POWERS OF TEN TABLE (GTSTG) ! 4485: # ! 4486: reav0: .float 0f0.0 # 0.0 ! 4487: reap1: .float 0f0.1 # 0.1 ! 4488: reap5: .float 0f0.5 # 0.5 ! 4489: reav1: .float 0f1.0 # 10**0 ! 4490: reavt: .float 0f1.0e+1 # 10**1 ! 4491: .float 0f1.0e+2 # 10**2 ! 4492: .float 0f1.0e+3 # 10**3 ! 4493: .float 0f1.0e+4 # 10**4 ! 4494: .float 0f1.0e+5 # 10**5 ! 4495: .float 0f1.0e+6 # 10**6 ! 4496: .float 0f1.0e+7 # 10**7 ! 4497: .float 0f1.0e+8 # 10**8 ! 4498: .float 0f1.0e+9 # 10**9 ! 4499: reatt: .float 0f1.0e+10 # 10**10 ! 4500: #page ! 4501: # ! 4502: # STRING CONSTANTS (SCBLK FORMAT) FOR DTYPE PROCEDURE ! 4503: # ! 4504: scarr: .long b$scl # array ! 4505: .long 5 ! 4506: .ascii "ARRAY" ! 4507: .align 2 ! 4508: # ! 4509: scbuf: .long b$scl # buffer ! 4510: .long 6 ! 4511: .ascii "BUFFER" ! 4512: .align 2 ! 4513: # ! 4514: sccod: .long b$scl # code ! 4515: .long 4 ! 4516: .ascii "CODE" ! 4517: .align 2 ! 4518: # ! 4519: scexp: .long b$scl # expression ! 4520: .long 10 ! 4521: .ascii "EXPRESSION" ! 4522: .align 2 ! 4523: # ! 4524: scext: .long b$scl # external ! 4525: .long 8 ! 4526: .ascii "EXTERNAL" ! 4527: .align 2 ! 4528: # ! 4529: scint: .long b$scl # integer ! 4530: .long 7 ! 4531: .ascii "INTEGER" ! 4532: .align 2 ! 4533: # ! 4534: scnam: .long b$scl # name ! 4535: .long 4 ! 4536: .ascii "NAME" ! 4537: .align 2 ! 4538: # ! 4539: scnum: .long b$scl # numeric ! 4540: .long 7 ! 4541: .ascii "NUMERIC" ! 4542: .align 2 ! 4543: # ! 4544: scpat: .long b$scl # pattern ! 4545: .long 7 ! 4546: .ascii "PATTERN" ! 4547: .align 2 ! 4548: # ! 4549: screa: .long b$scl # real ! 4550: .long 4 ! 4551: .ascii "REAL" ! 4552: .align 2 ! 4553: # ! 4554: scstr: .long b$scl # string ! 4555: .long 6 ! 4556: .ascii "STRING" ! 4557: .align 2 ! 4558: # ! 4559: sctab: .long b$scl # table ! 4560: .long 5 ! 4561: .ascii "TABLE" ! 4562: .align 2 ! 4563: #page ! 4564: # ! 4565: # STRING CONSTANTS (SCBLK FORMAT) FOR KVRTN (SEE RETRN) ! 4566: # ! 4567: scfrt: .long b$scl # freturn ! 4568: .long 7 ! 4569: .ascii "FRETURN" ! 4570: .align 2 ! 4571: # ! 4572: scnrt: .long b$scl # nreturn ! 4573: .long 7 ! 4574: .ascii "NRETURN" ! 4575: .align 2 ! 4576: # ! 4577: scrtn: .long b$scl # return ! 4578: .long 6 ! 4579: .ascii "RETURN" ! 4580: .align 2 ! 4581: # ! 4582: # DATATYPE NAME TABLE FOR DTYPE PROCEDURE. THE ORDER OF ! 4583: # THESE ENTRIES IS TIED TO THE B$XXX DEFINITIONS FOR BLOCKS ! 4584: # ! 4585: scnmt: .long scarr # arblk array ! 4586: .long scbuf # bfblk buffer ! 4587: .long sccod # cdblk code ! 4588: .long scexp # exblk expression ! 4589: .long scint # icblk integer ! 4590: .long scnam # nmblk name ! 4591: .long scpat # p0blk pattern ! 4592: .long scpat # p1blk pattern ! 4593: .long scpat # p2blk pattern ! 4594: .long screa # rcblk real ! 4595: .long scstr # scblk string ! 4596: .long scexp # seblk expression ! 4597: .long sctab # tbblk table ! 4598: .long scarr # vcblk array ! 4599: .long scext # xnblk external ! 4600: .long scext # xrblk external ! 4601: # ! 4602: # STRING CONSTANT FOR REAL ZERO ! 4603: # ! 4604: scre0: .long b$scl ! 4605: .long 2 ! 4606: .ascii "0." ! 4607: .align 2 ! 4608: #page ! 4609: # ! 4610: # USED TO RE-INITIALISE KVSTL ! 4611: # ! 4612: stlim: .long 50000 # default statement limit ! 4613: # ! 4614: # DUMMY FUNCTION BLOCK USED FOR UNDEFINED FUNCTIONS ! 4615: # ! 4616: stndf: .long o$fun # ptr to undefined function err call ! 4617: .long 0 # dummy fargs count for call circuit ! 4618: # ! 4619: # DUMMY CODE BLOCK USED FOR UNDEFINED LABELS ! 4620: # ! 4621: stndl: .long l$und # code ptr points to undefined lbl ! 4622: # ! 4623: # DUMMY OPERATOR BLOCK USED FOR UNDEFINED OPERATORS ! 4624: # ! 4625: stndo: .long o$oun # ptr to undefined operator err call ! 4626: .long 0 # dummy fargs count for call circuit ! 4627: # ! 4628: # STANDARD VARIABLE BLOCK. THIS BLOCK IS USED TO INITIALIZE ! 4629: # THE FIRST SEVEN FIELDS OF A NEWLY CONSTRUCTED VRBLK. ! 4630: # ITS FORMAT IS TIED TO THE VRBLK DEFINITIONS (SEE GTNVR). ! 4631: # ! 4632: stnvr: .long b$vrl # vrget ! 4633: .long b$vrs # vrsto ! 4634: .long nulls # vrval ! 4635: .long b$vrg # vrtra ! 4636: .long stndl # vrlbl ! 4637: .long stndf # vrfnc ! 4638: .long 0 # vrnxt ! 4639: #page ! 4640: # ! 4641: # MESSAGES USED IN END OF RUN PROCESSING (STOPR) ! 4642: # ! 4643: stpm1: .long b$scl # in statement ! 4644: .long 12 ! 4645: .ascii "IN STATEMENT" ! 4646: .align 2 ! 4647: # ! 4648: stpm2: .long b$scl ! 4649: .long 14 ! 4650: .ascii "STMTS EXECUTED" ! 4651: .align 2 ! 4652: # ! 4653: stpm3: .long b$scl ! 4654: .long 13 ! 4655: .ascii "RUN TIME-MSEC" ! 4656: .align 2 ! 4657: # ! 4658: stpm4: .long b$scl ! 4659: .long 12 ! 4660: .ascii "MCSEC / STMT" ! 4661: .align 2 ! 4662: # ! 4663: stpm5: .long b$scl ! 4664: .long 13 ! 4665: .ascii "REGENERATIONS" ! 4666: .align 2 ! 4667: # ! 4668: # CHARS FOR /TU/ ENDING CODE ! 4669: # ! 4670: strtu: .ascii "TU" ! 4671: .align 2 ! 4672: # ! 4673: # TABLE USED BY CONVERT FUNCTION TO CHECK DATATYPE NAME ! 4674: # THE ENTRIES ARE ORDERED TO CORRESPOND TO BRANCH TABLE ! 4675: # IN S$CNV ! 4676: # ! 4677: svctb: .long scstr # string ! 4678: .long scint # integer ! 4679: .long scnam # name ! 4680: .long scpat # pattern ! 4681: .long scarr # array ! 4682: .long sctab # table ! 4683: .long scexp # expression ! 4684: .long sccod # code ! 4685: .long scnum # numeric ! 4686: .long screa # real ! 4687: .long scbuf # buffer ! 4688: .long 0 # zero marks end of list ! 4689: #page ! 4690: # ! 4691: # MESSAGES (SCBLK FORMAT) USED BY TRACE PROCEDURES ! 4692: # ! 4693: # ! 4694: tmasb: .long b$scl # asterisks for trace statement no ! 4695: .long 13 ! 4696: .ascii "************ " ! 4697: .align 2 ! 4698: # ! 4699: tmbeb: .long b$scl # blank-equal-blank ! 4700: .long 3 ! 4701: .ascii " = " ! 4702: .align 2 ! 4703: # ! 4704: # DUMMY TRBLK FOR EXPRESSION VARIABLE ! 4705: # ! 4706: trbev: .long b$trt # dummy trblk ! 4707: # ! 4708: # DUMMY TRBLK FOR KEYWORD VARIABLE ! 4709: # ! 4710: trbkv: .long b$trt # dummy trblk ! 4711: # ! 4712: # DUMMY CODE BLOCK TO RETURN CONTROL TO TRXEQ PROCEDURE ! 4713: # ! 4714: trxdr: .long o$txr # block points to return routine ! 4715: trxdc: .long trxdr # pointer to block ! 4716: #page ! 4717: # ! 4718: # STANDARD VARIABLE BLOCKS ! 4719: # ! 4720: # SEE SVBLK FORMAT FOR FULL DETAILS OF THE FORMAT. THE ! 4721: # VRBLKS ARE ORDERED BY LENGTH AND WITHIN EACH LENGTH THE ! 4722: # ORDER IS ALPHABETICAL BY NAME OF THE VARIABLE. ! 4723: # ! 4724: v$eqf: .long svfpr # eq ! 4725: .long 2 ! 4726: .ascii "EQ" ! 4727: .align 2 ! 4728: .long s$eqf ! 4729: .long 2 ! 4730: # ! 4731: v$gef: .long svfpr # ge ! 4732: .long 2 ! 4733: .ascii "GE" ! 4734: .align 2 ! 4735: .long s$gef ! 4736: .long 2 ! 4737: # ! 4738: v$gtf: .long svfpr # gt ! 4739: .long 2 ! 4740: .ascii "GT" ! 4741: .align 2 ! 4742: .long s$gtf ! 4743: .long 2 ! 4744: # ! 4745: v$lef: .long svfpr # le ! 4746: .long 2 ! 4747: .ascii "LE" ! 4748: .align 2 ! 4749: .long s$lef ! 4750: .long 2 ! 4751: # ! 4752: v$ltf: .long svfpr # lt ! 4753: .long 2 ! 4754: .ascii "LT" ! 4755: .align 2 ! 4756: .long s$ltf ! 4757: .long 2 ! 4758: # ! 4759: v$nef: .long svfpr # ne ! 4760: .long 2 ! 4761: .ascii "NE" ! 4762: .align 2 ! 4763: .long s$nef ! 4764: .long 2 ! 4765: # ! 4766: v$any: .long svfnp # any ! 4767: .long 3 ! 4768: .ascii "ANY" ! 4769: .align 2 ! 4770: .long s$any ! 4771: .long 1 ! 4772: # ! 4773: v$arb: .long svkvc # arb ! 4774: .long 3 ! 4775: .ascii "ARB" ! 4776: .align 2 ! 4777: .long k$arb ! 4778: .long ndarb ! 4779: #page ! 4780: # ! 4781: # STANDARD VARIABLE BLOCKS (CONTINUED) ! 4782: # ! 4783: v$arg: .long svfnn # arg ! 4784: .long 3 ! 4785: .ascii "ARG" ! 4786: .align 2 ! 4787: .long s$arg ! 4788: .long 2 ! 4789: # ! 4790: v$bal: .long svkvc # bal ! 4791: .long 3 ! 4792: .ascii "BAL" ! 4793: .align 2 ! 4794: .long k$bal ! 4795: .long ndbal ! 4796: # ! 4797: v$end: .long svlbl # end ! 4798: .long 3 ! 4799: .ascii "END" ! 4800: .align 2 ! 4801: .long l$end ! 4802: # ! 4803: v$len: .long svfnp # len ! 4804: .long 3 ! 4805: .ascii "LEN" ! 4806: .align 2 ! 4807: .long s$len ! 4808: .long 1 ! 4809: # ! 4810: v$leq: .long svfpr # leq ! 4811: .long 3 ! 4812: .ascii "LEQ" ! 4813: .align 2 ! 4814: .long s$leq ! 4815: .long 2 ! 4816: # ! 4817: v$lge: .long svfpr # lge ! 4818: .long 3 ! 4819: .ascii "LGE" ! 4820: .align 2 ! 4821: .long s$lge ! 4822: .long 2 ! 4823: # ! 4824: v$lgt: .long svfpr # lgt ! 4825: .long 3 ! 4826: .ascii "LGT" ! 4827: .align 2 ! 4828: .long s$lgt ! 4829: .long 2 ! 4830: # ! 4831: v$lle: .long svfpr # lle ! 4832: .long 3 ! 4833: .ascii "LLE" ! 4834: .align 2 ! 4835: .long s$lle ! 4836: .long 2 ! 4837: #page ! 4838: # ! 4839: # STANDARD VARIABLE BLOCKS (CONTINUED) ! 4840: # ! 4841: v$llt: .long svfpr # llt ! 4842: .long 3 ! 4843: .ascii "LLT" ! 4844: .align 2 ! 4845: .long s$llt ! 4846: .long 2 ! 4847: # ! 4848: v$lne: .long svfpr # lne ! 4849: .long 3 ! 4850: .ascii "LNE" ! 4851: .align 2 ! 4852: .long s$lne ! 4853: .long 2 ! 4854: # ! 4855: v$pos: .long svfnp # pos ! 4856: .long 3 ! 4857: .ascii "POS" ! 4858: .align 2 ! 4859: .long s$pos ! 4860: .long 1 ! 4861: # ! 4862: v$rem: .long svkvc # rem ! 4863: .long 3 ! 4864: .ascii "REM" ! 4865: .align 2 ! 4866: .long k$rem ! 4867: .long ndrem ! 4868: # ! 4869: v$set: .long svfnn # set ! 4870: .long 3 ! 4871: .ascii "SET" ! 4872: .align 2 ! 4873: .long s$set ! 4874: .long 3 ! 4875: # ! 4876: v$tab: .long svfnp # tab ! 4877: .long 3 ! 4878: .ascii "TAB" ! 4879: .align 2 ! 4880: .long s$tab ! 4881: .long 1 ! 4882: # ! 4883: v$cas: .long svknm # case ! 4884: .long 4 ! 4885: .ascii "CASE" ! 4886: .align 2 ! 4887: .long k$cas ! 4888: # ! 4889: v$chr: .long svfnp # char ! 4890: .long 4 ! 4891: .ascii "CHAR" ! 4892: .align 2 ! 4893: .long s$chr ! 4894: .long 1 ! 4895: # ! 4896: v$cod: .long svfnk # code ! 4897: .long 4 ! 4898: .ascii "CODE" ! 4899: .align 2 ! 4900: .long k$cod ! 4901: .long s$cod ! 4902: .long 1 ! 4903: # ! 4904: v$cop: .long svfnn # copy ! 4905: .long 4 ! 4906: .ascii "COPY" ! 4907: .align 2 ! 4908: .long s$cop ! 4909: .long 1 ! 4910: #page ! 4911: # ! 4912: # STANDARD VARIABLE BLOCKS (CONTINUED) ! 4913: # ! 4914: v$dat: .long svfnn # data ! 4915: .long 4 ! 4916: .ascii "DATA" ! 4917: .align 2 ! 4918: .long s$dat ! 4919: .long 1 ! 4920: # ! 4921: v$dte: .long svfnn # date ! 4922: .long 4 ! 4923: .ascii "DATE" ! 4924: .align 2 ! 4925: .long s$dte ! 4926: .long 0 ! 4927: # ! 4928: v$dmp: .long svfnk # dump ! 4929: .long 4 ! 4930: .ascii "DUMP" ! 4931: .align 2 ! 4932: .long k$dmp ! 4933: .long s$dmp ! 4934: .long 1 ! 4935: # ! 4936: v$dup: .long svfnn # dupl ! 4937: .long 4 ! 4938: .ascii "DUPL" ! 4939: .align 2 ! 4940: .long s$dup ! 4941: .long 2 ! 4942: # ! 4943: v$evl: .long svfnn # eval ! 4944: .long 4 ! 4945: .ascii "EVAL" ! 4946: .align 2 ! 4947: .long s$evl ! 4948: .long 1 ! 4949: # ! 4950: v$ext: .long svfnn # exit ! 4951: .long 4 ! 4952: .ascii "EXIT" ! 4953: .align 2 ! 4954: .long s$ext ! 4955: .long 1 ! 4956: # ! 4957: v$fal: .long svkvc # fail ! 4958: .long 4 ! 4959: .ascii "FAIL" ! 4960: .align 2 ! 4961: .long k$fal ! 4962: .long ndfal ! 4963: # ! 4964: v$hst: .long svfnn # host ! 4965: .long 4 ! 4966: .ascii "HOST" ! 4967: .align 2 ! 4968: .long s$hst ! 4969: .long 3 ! 4970: #page ! 4971: # ! 4972: # STANDARD VARIABLE BLOCKS (CONTINUED) ! 4973: # ! 4974: v$itm: .long svfnf # item ! 4975: .long 4 ! 4976: .ascii "ITEM" ! 4977: .align 2 ! 4978: .long s$itm ! 4979: .long 999 ! 4980: # ! 4981: v$lod: .long svfnn # load ! 4982: .long 4 ! 4983: .ascii "LOAD" ! 4984: .align 2 ! 4985: .long s$lod ! 4986: .long 2 ! 4987: # ! 4988: v$lpd: .long svfnp # lpad ! 4989: .long 4 ! 4990: .ascii "LPAD" ! 4991: .align 2 ! 4992: .long s$lpd ! 4993: .long 3 ! 4994: # ! 4995: v$rpd: .long svfnp # rpad ! 4996: .long 4 ! 4997: .ascii "RPAD" ! 4998: .align 2 ! 4999: .long s$rpd ! 5000: .long 3 ! 5001: # ! 5002: v$rps: .long svfnp # rpos ! 5003: .long 4 ! 5004: .ascii "RPOS" ! 5005: .align 2 ! 5006: .long s$rps ! 5007: .long 1 ! 5008: # ! 5009: v$rtb: .long svfnp # rtab ! 5010: .long 4 ! 5011: .ascii "RTAB" ! 5012: .align 2 ! 5013: .long s$rtb ! 5014: .long 1 ! 5015: # ! 5016: v$si$: .long svfnp # size ! 5017: .long 4 ! 5018: .ascii "SIZE" ! 5019: .align 2 ! 5020: .long s$si$ ! 5021: .long 1 ! 5022: # ! 5023: # ! 5024: v$srt: .long svfnn # sort ! 5025: .long 4 ! 5026: .ascii "SORT" ! 5027: .align 2 ! 5028: .long s$srt ! 5029: .long 2 ! 5030: v$spn: .long svfnp # span ! 5031: .long 4 ! 5032: .ascii "SPAN" ! 5033: .align 2 ! 5034: .long s$spn ! 5035: .long 1 ! 5036: #page ! 5037: # ! 5038: # STANDARD VARIABLE BLOCKS (CONTINUED) ! 5039: # ! 5040: v$stn: .long svknm # stno ! 5041: .long 4 ! 5042: .ascii "STNO" ! 5043: .align 2 ! 5044: .long k$stn ! 5045: # ! 5046: v$tim: .long svfnn # time ! 5047: .long 4 ! 5048: .ascii "TIME" ! 5049: .align 2 ! 5050: .long s$tim ! 5051: .long 0 ! 5052: # ! 5053: v$trm: .long svfnk # trim ! 5054: .long 4 ! 5055: .ascii "TRIM" ! 5056: .align 2 ! 5057: .long k$trm ! 5058: .long s$trm ! 5059: .long 1 ! 5060: # ! 5061: v$abe: .long svknm # abend ! 5062: .long 5 ! 5063: .ascii "ABEND" ! 5064: .align 2 ! 5065: .long k$abe ! 5066: # ! 5067: v$abo: .long svkvl # abort ! 5068: .long 5 ! 5069: .ascii "ABORT" ! 5070: .align 2 ! 5071: .long k$abo ! 5072: .long l$abo ! 5073: .long ndabo ! 5074: # ! 5075: v$app: .long svfnf # apply ! 5076: .long 5 ! 5077: .ascii "APPLY" ! 5078: .align 2 ! 5079: .long s$app ! 5080: .long 999 ! 5081: # ! 5082: v$abn: .long svfnp # arbno ! 5083: .long 5 ! 5084: .ascii "ARBNO" ! 5085: .align 2 ! 5086: .long s$abn ! 5087: .long 1 ! 5088: # ! 5089: v$arr: .long svfnn # array ! 5090: .long 5 ! 5091: .ascii "ARRAY" ! 5092: .align 2 ! 5093: .long s$arr ! 5094: .long 2 ! 5095: #page ! 5096: # ! 5097: # STANDARD VARIABLE BLOCKS (CONTINUED) ! 5098: # ! 5099: v$brk: .long svfnp # break ! 5100: .long 5 ! 5101: .ascii "BREAK" ! 5102: .align 2 ! 5103: .long s$brk ! 5104: .long 1 ! 5105: # ! 5106: v$clr: .long svfnn # clear ! 5107: .long 5 ! 5108: .ascii "CLEAR" ! 5109: .align 2 ! 5110: .long s$clr ! 5111: .long 1 ! 5112: # ! 5113: v$ejc: .long svfnn # eject ! 5114: .long 5 ! 5115: .ascii "EJECT" ! 5116: .align 2 ! 5117: .long s$ejc ! 5118: .long 1 ! 5119: # ! 5120: v$fen: .long svfpk # fence ! 5121: .long 5 ! 5122: .ascii "FENCE" ! 5123: .align 2 ! 5124: .long k$fen ! 5125: .long s$fnc ! 5126: .long 1 ! 5127: .long ndfen ! 5128: # ! 5129: v$fld: .long svfnn # field ! 5130: .long 5 ! 5131: .ascii "FIELD" ! 5132: .align 2 ! 5133: .long s$fld ! 5134: .long 2 ! 5135: # ! 5136: v$idn: .long svfpr # ident ! 5137: .long 5 ! 5138: .ascii "IDENT" ! 5139: .align 2 ! 5140: .long s$idn ! 5141: .long 2 ! 5142: # ! 5143: v$inp: .long svfnk # input ! 5144: .long 5 ! 5145: .ascii "INPUT" ! 5146: .align 2 ! 5147: .long k$inp ! 5148: .long s$inp ! 5149: .long 3 ! 5150: # ! 5151: v$loc: .long svfnn # local ! 5152: .long 5 ! 5153: .ascii "LOCAL" ! 5154: .align 2 ! 5155: .long s$loc ! 5156: .long 2 ! 5157: #page ! 5158: # ! 5159: # STANDARD VARIABLE BLOCKS (CONTINUED) ! 5160: # ! 5161: v$ops: .long svfnn # opsyn ! 5162: .long 5 ! 5163: .ascii "OPSYN" ! 5164: .align 2 ! 5165: .long s$ops ! 5166: .long 3 ! 5167: # ! 5168: v$rmd: .long svfnp # remdr ! 5169: .long 5 ! 5170: .ascii "REMDR" ! 5171: .align 2 ! 5172: .long s$rmd ! 5173: .long 2 ! 5174: # ! 5175: v$rsr: .long svfnn # rsort ! 5176: .long 5 ! 5177: .ascii "RSORT" ! 5178: .align 2 ! 5179: .long s$rsr ! 5180: .long 2 ! 5181: # ! 5182: v$tbl: .long svfnn # table ! 5183: .long 5 ! 5184: .ascii "TABLE" ! 5185: .align 2 ! 5186: .long s$tbl ! 5187: .long 3 ! 5188: # ! 5189: v$tra: .long svfnk # trace ! 5190: .long 5 ! 5191: .ascii "TRACE" ! 5192: .align 2 ! 5193: .long k$tra ! 5194: .long s$tra ! 5195: .long 4 ! 5196: # ! 5197: v$anc: .long svknm # anchor ! 5198: .long 6 ! 5199: .ascii "ANCHOR" ! 5200: .align 2 ! 5201: .long k$anc ! 5202: # ! 5203: v$apn: .long svfnn ! 5204: .long 6 ! 5205: .ascii "APPEND" ! 5206: .align 2 ! 5207: .long s$apn ! 5208: .long 2 ! 5209: # ! 5210: v$bkx: .long svfnp # breakx ! 5211: .long 6 ! 5212: .ascii "BREAKX" ! 5213: .align 2 ! 5214: .long s$bkx ! 5215: .long 1 ! 5216: # ! 5217: v$buf: .long svfnn # buffer ! 5218: .long 6 ! 5219: .ascii "BUFFER" ! 5220: .align 2 ! 5221: .long s$buf ! 5222: .long 2 ! 5223: # ! 5224: v$def: .long svfnn # define ! 5225: .long 6 ! 5226: .ascii "DEFINE" ! 5227: .align 2 ! 5228: .long s$def ! 5229: .long 2 ! 5230: # ! 5231: v$det: .long svfnn # detach ! 5232: .long 6 ! 5233: .ascii "DETACH" ! 5234: .align 2 ! 5235: .long s$det ! 5236: .long 1 ! 5237: #page ! 5238: # ! 5239: # STANDARD VARIABLE BLOCKS (CONTINUED) ! 5240: # ! 5241: v$dif: .long svfpr # differ ! 5242: .long 6 ! 5243: .ascii "DIFFER" ! 5244: .align 2 ! 5245: .long s$dif ! 5246: .long 2 ! 5247: # ! 5248: v$ftr: .long svknm # ftrace ! 5249: .long 6 ! 5250: .ascii "FTRACE" ! 5251: .align 2 ! 5252: .long k$ftr ! 5253: # ! 5254: v$ins: .long svfnn # insert ! 5255: .long 6 ! 5256: .ascii "INSERT" ! 5257: .align 2 ! 5258: .long s$ins ! 5259: .long 4 ! 5260: # ! 5261: v$lst: .long svknm # lastno ! 5262: .long 6 ! 5263: .ascii "LASTNO" ! 5264: .align 2 ! 5265: .long k$lst ! 5266: # ! 5267: v$nay: .long svfnp # notany ! 5268: .long 6 ! 5269: .ascii "NOTANY" ! 5270: .align 2 ! 5271: .long s$nay ! 5272: .long 1 ! 5273: # ! 5274: v$oup: .long svfnk # output ! 5275: .long 6 ! 5276: .ascii "OUTPUT" ! 5277: .align 2 ! 5278: .long k$oup ! 5279: .long s$oup ! 5280: .long 3 ! 5281: # ! 5282: v$ret: .long svlbl # return ! 5283: .long 6 ! 5284: .ascii "RETURN" ! 5285: .align 2 ! 5286: .long l$rtn ! 5287: # ! 5288: v$rew: .long svfnn # rewind ! 5289: .long 6 ! 5290: .ascii "REWIND" ! 5291: .align 2 ! 5292: .long s$rew ! 5293: .long 1 ! 5294: # ! 5295: v$stt: .long svfnn # stoptr ! 5296: .long 6 ! 5297: .ascii "STOPTR" ! 5298: .align 2 ! 5299: .long s$stt ! 5300: .long 2 ! 5301: #page ! 5302: # ! 5303: # STANDARD VARIABLE BLOCKS (CONTINUED) ! 5304: # ! 5305: v$sub: .long svfnn # substr ! 5306: .long 6 ! 5307: .ascii "SUBSTR" ! 5308: .align 2 ! 5309: .long s$sub ! 5310: .long 3 ! 5311: # ! 5312: v$unl: .long svfnn # unload ! 5313: .long 6 ! 5314: .ascii "UNLOAD" ! 5315: .align 2 ! 5316: .long s$unl ! 5317: .long 1 ! 5318: # ! 5319: v$col: .long svfnn # collect ! 5320: .long 7 ! 5321: .ascii "COLLECT" ! 5322: .align 2 ! 5323: .long s$col ! 5324: .long 1 ! 5325: # ! 5326: v$cnv: .long svfnn # convert ! 5327: .long 7 ! 5328: .ascii "CONVERT" ! 5329: .align 2 ! 5330: .long s$cnv ! 5331: .long 2 ! 5332: # ! 5333: v$enf: .long svfnn # endfile ! 5334: .long 7 ! 5335: .ascii "ENDFILE" ! 5336: .align 2 ! 5337: .long s$enf ! 5338: .long 1 ! 5339: # ! 5340: v$etx: .long svknm # errtext ! 5341: .long 7 ! 5342: .ascii "ERRTEXT" ! 5343: .align 2 ! 5344: .long k$etx ! 5345: # ! 5346: v$ert: .long svknm # errtype ! 5347: .long 7 ! 5348: .ascii "ERRTYPE" ! 5349: .align 2 ! 5350: .long k$ert ! 5351: # ! 5352: v$frt: .long svlbl # freturn ! 5353: .long 7 ! 5354: .ascii "FRETURN" ! 5355: .align 2 ! 5356: .long l$frt ! 5357: # ! 5358: v$int: .long svfpr # integer ! 5359: .long 7 ! 5360: .ascii "INTEGER" ! 5361: .align 2 ! 5362: .long s$int ! 5363: .long 1 ! 5364: # ! 5365: v$nrt: .long svlbl # nreturn ! 5366: .long 7 ! 5367: .ascii "NRETURN" ! 5368: .align 2 ! 5369: .long l$nrt ! 5370: #page ! 5371: # ! 5372: # STANDARD VARIABLE BLOCKS (CONTINUED) ! 5373: # ! 5374: # ! 5375: v$pfl: .long svknm # profile ! 5376: .long 7 ! 5377: .ascii "PROFILE" ! 5378: .align 2 ! 5379: .long k$pfl ! 5380: # ! 5381: v$rpl: .long svfnp # replace ! 5382: .long 7 ! 5383: .ascii "REPLACE" ! 5384: .align 2 ! 5385: .long s$rpl ! 5386: .long 3 ! 5387: # ! 5388: v$rvs: .long svfnp # reverse ! 5389: .long 7 ! 5390: .ascii "REVERSE" ! 5391: .align 2 ! 5392: .long s$rvs ! 5393: .long 1 ! 5394: # ! 5395: v$rtn: .long svknm # rtntype ! 5396: .long 7 ! 5397: .ascii "RTNTYPE" ! 5398: .align 2 ! 5399: .long k$rtn ! 5400: # ! 5401: v$stx: .long svfnn # setexit ! 5402: .long 7 ! 5403: .ascii "SETEXIT" ! 5404: .align 2 ! 5405: .long s$stx ! 5406: .long 1 ! 5407: # ! 5408: v$stc: .long svknm # stcount ! 5409: .long 7 ! 5410: .ascii "STCOUNT" ! 5411: .align 2 ! 5412: .long k$stc ! 5413: # ! 5414: v$stl: .long svknm # stlimit ! 5415: .long 7 ! 5416: .ascii "STLIMIT" ! 5417: .align 2 ! 5418: .long k$stl ! 5419: # ! 5420: v$suc: .long svkvc # succeed ! 5421: .long 7 ! 5422: .ascii "SUCCEED" ! 5423: .align 2 ! 5424: .long k$suc ! 5425: .long ndsuc ! 5426: # ! 5427: v$alp: .long svkwc # alphabet ! 5428: .long 8 ! 5429: .ascii "ALPHABET" ! 5430: .align 2 ! 5431: .long k$alp ! 5432: # ! 5433: v$cnt: .long svlbl # continue ! 5434: .long 8 ! 5435: .ascii "CONTINUE" ! 5436: .align 2 ! 5437: .long l$cnt ! 5438: #page ! 5439: # ! 5440: # STANDARD VARIABLE BLOCKS (CONTINUED) ! 5441: # ! 5442: v$dtp: .long svfnp # datatype ! 5443: .long 8 ! 5444: .ascii "DATATYPE" ! 5445: .align 2 ! 5446: .long s$dtp ! 5447: .long 1 ! 5448: # ! 5449: v$erl: .long svknm # errlimit ! 5450: .long 8 ! 5451: .ascii "ERRLIMIT" ! 5452: .align 2 ! 5453: .long k$erl ! 5454: # ! 5455: v$fnc: .long svknm # fnclevel ! 5456: .long 8 ! 5457: .ascii "FNCLEVEL" ! 5458: .align 2 ! 5459: .long k$fnc ! 5460: # ! 5461: v$mxl: .long svknm # maxlngth ! 5462: .long 8 ! 5463: .ascii "MAXLNGTH" ! 5464: .align 2 ! 5465: .long k$mxl ! 5466: # ! 5467: v$ter: .long 0 # terminal ! 5468: .long 8 ! 5469: .ascii "TERMINAL" ! 5470: .align 2 ! 5471: .long 0 ! 5472: # ! 5473: v$pro: .long svfnn # prototype ! 5474: .long 9 ! 5475: .ascii "PROTOTYPE" ! 5476: .align 2 ! 5477: .long s$pro ! 5478: .long 1 ! 5479: # ! 5480: .long 0 # dummy entry to end list ! 5481: .long 10 # length gt 9 (prototype) ! 5482: #page ! 5483: # ! 5484: # LIST OF SVBLK POINTERS FOR KEYWORDS TO BE DUMPED. THE ! 5485: # LIST IS IN THE ORDER WHICH APPEARS ON THE DUMP OUTPUT. ! 5486: # ! 5487: vdmkw: .long v$anc # anchor ! 5488: .long v$cas # ccase ! 5489: .long v$cod # code ! 5490: .long v$dmp # dump ! 5491: .long v$erl # errlimit ! 5492: .long v$etx # errtext ! 5493: .long v$ert # errtype ! 5494: .long v$fnc # fnclevel ! 5495: .long v$ftr # ftrace ! 5496: .long v$inp # input ! 5497: .long v$lst # lastno ! 5498: .long v$mxl # maxlength ! 5499: .long v$oup # output ! 5500: .long v$pfl # profile ! 5501: .long v$rtn # rtntype ! 5502: .long v$stc # stcount ! 5503: .long v$stl # stlimit ! 5504: .long v$stn # stno ! 5505: .long v$tra # trace ! 5506: .long v$trm # trim ! 5507: .long 0 # end of list ! 5508: # ! 5509: # TABLE USED BY GTNVR TO SEARCH SVBLK LISTS ! 5510: # ! 5511: vsrch: .long 0 # dummy entry to get proper indexing ! 5512: .long v$eqf # start of 1 char variables (none) ! 5513: .long v$eqf # start of 2 char variables ! 5514: .long v$any # start of 3 char variables ! 5515: .long v$cas # start of 4 char variables ! 5516: .long v$abe # start of 5 char variables ! 5517: .long v$anc # start of 6 char variables ! 5518: .long v$col # start of 7 char variables ! 5519: .long v$alp # start of 8 char variables ! 5520: .long v$pro # start of 9 char variables ! 5521: #title s p i t b o l -- working storage section ! 5522: # ! 5523: # THE WORKING STORAGE SECTION CONTAINS AREAS WHICH ARE ! 5524: # CHANGED DURING EXECUTION OF THE PROGRAM. THE VALUE ! 5525: # ASSEMBLED IS THE INITIAL VALUE BEFORE EXECUTION STARTS. ! 5526: # ! 5527: # ALL THESE AREAS ARE FIXED LENGTH AREAS. VARIABLE LENGTH ! 5528: # DATA IS STORED IN THE STATIC OR DYNAMIC REGIONS OF THE ! 5529: # ALLOCATED DATA AREAS. ! 5530: # ! 5531: # THE VALUES IN THIS AREA ARE DESCRIBED EITHER AS WORK ! 5532: # AREAS OR AS GLOBAL VALUES. A WORK AREA IS USED IN AN ! 5533: # EPHEMERAL MANNER AND THE VALUE IS NOT SAVED FROM ONE ! 5534: # ENTRY INTO A ROUTINE TO ANOTHER. A GLOBAL VALUE IS A ! 5535: # LESS TEMPORARY LOCATION WHOSE VALUE IS SAVED FROM ONE ! 5536: # CALL TO ANOTHER. ! 5537: # ! 5538: # A GENERAL PART OF THE APPROACH IN THIS PROGRAM IS NOT ! 5539: # TO OVERLAP WORK AREAS BETWEEN PROCEDURES EVEN THOUGH A ! 5540: # SMALL AMOUNT OF SPACE COULD BE SAVED. SUCH OVERLAP IS ! 5541: # CONSIDERED A SOURCE OF PROGRAM ERRORS AND DECREASES THE ! 5542: # INFORMATION LEFT BEHIND AFTER A SYSTEM CRASH OF ANY KIND. ! 5543: # ! 5544: # THE NAMES OF THESE LOCATIONS ARE LABELS WITH FIVE LETTER ! 5545: # (A-Y,$) NAMES. AS FAR AS POSSIBLE THE ORDER IS KEPT ! 5546: # ALPHABETICAL BY THESE NAMES BUT IN SOME CASES THERE ! 5547: # ARE SLIGHT DEPARTURES CAUSED BY OTHER ORDER REQUIREMENTS. ! 5548: # ! 5549: # UNLESS OTHERWISE DOCUMENTED, THE ORDER OF WORK AREAS ! 5550: # DOES NOT AFFECT THE EXECUTION OF THE SPITBOL PROGRAM. ! 5551: # ! 5552: .data 1 ! 5553: #sec # start of working storage section ! 5554: #page ! 5555: # ! 5556: # THIS AREA IS NOT CLEARED BY INITIAL CODE ! 5557: # ! 5558: cmlab: .long b$scl # string used to check label legality ! 5559: .long 2 ! 5560: .ascii " " ! 5561: .align 2 ! 5562: # ! 5563: # LABEL TO MARK START OF WORK AREA ! 5564: # ! 5565: aaaaa: .long 0 ! 5566: # ! 5567: # WORK AREAS FOR ALLOC PROCEDURE ! 5568: # ! 5569: aldyn: .long 0 # amount of dynamic store ! 5570: alfsf: .long 0 # factor in free store pcntage check ! 5571: allia: .long 0 # dump ia ! 5572: allsv: .long 0 # save wb in alloc ! 5573: # ! 5574: # WORK AREAS FOR ALOST PROCEDURE ! 5575: # ! 5576: alsta: .long 0 # save wa in alost ! 5577: # ! 5578: # SAVE AREAS FOR ARRAY FUNCTION (S$ARR) ! 5579: # ! 5580: arcdm: .long 0 # count dimensions ! 5581: arnel: .long 0 # count elements ! 5582: arptr: .long 0 # offset ptr into arblk ! 5583: arsvl: .long 0 # save integer low bound ! 5584: #page ! 5585: # WORK AREAS FOR ARREF ROUTINE ! 5586: # ! 5587: arfsi: .long 0 # save current evolving subscript ! 5588: arfxs: .long 0 # save base stack pointer ! 5589: # ! 5590: # WORK AREAS FOR B$EFC BLOCK ROUTINE ! 5591: # ! 5592: befof: .long 0 # save offset ptr into efblk ! 5593: # ! 5594: # WORK AREAS FOR B$PFC BLOCK ROUTINE ! 5595: # ! 5596: bpfpf: .long 0 # save pfblk pointer ! 5597: bpfsv: .long 0 # save old function value ! 5598: bpfxt: .long 0 # pointer to stacked arguments ! 5599: # ! 5600: # SAVE AREAS FOR COLLECT FUNCTION (S$COL) ! 5601: # ! 5602: clsvi: .long 0 # save integer argument ! 5603: # ! 5604: # GLOBAL VALUES FOR CMPIL PROCEDURE ! 5605: # ! 5606: cmerc: .long 0 # count of initial compile errors ! 5607: cmpxs: .long 0 # save stack ptr in case of errors ! 5608: cmpsn: .long 1 # number of next statement to compile ! 5609: cmpss: .long 0 # save subroutine stack ptr ! 5610: # ! 5611: # WORK AREA FOR CNCRD ! 5612: # ! 5613: cnscc: .long 0 # pointer to control card string ! 5614: cnswc: .long 0 # word count ! 5615: cnr$t: .long 0 # pointer to r$ttl or r$stl ! 5616: cnttl: .long 0 # flag for -title, -stitl ! 5617: # ! 5618: # WORK AREAS FOR CONVERT FUNCTION (S$CNV) ! 5619: # ! 5620: cnvtp: .long 0 # save ptr into scvtb ! 5621: # ! 5622: # FLAG FOR SUPPRESSION OF COMPILATION STATISTICS. ! 5623: # ! 5624: cpsts: .long 0 # suppress comp. stats if non zero ! 5625: # ! 5626: # GLOBAL VALUES FOR CONTROL CARD SWITCHES ! 5627: # ! 5628: cswdb: .long 0 # 0/1 for -single/-double ! 5629: cswer: .long 0 # 0/1 for -errors/-noerrors ! 5630: cswex: .long 0 # 0/1 for -execute/-noexecute ! 5631: cswfl: .long 1 # 0/1 for -nofail/-fail ! 5632: cswin: .long iniln # xxx for -inxxx ! 5633: cswls: .long 1 # 0/1 for -nolist/-list ! 5634: cswno: .long 0 # 0/1 for -optimise/-noopt ! 5635: cswpr: .long 0 # 0/1 for -noprint/-print ! 5636: # ! 5637: # GLOBAL LOCATION USED BY PATST PROCEDURE ! 5638: # ! 5639: ctmsk: .long 0 # last bit position used in r$ctp ! 5640: curid: .long 0 # current id value ! 5641: #page ! 5642: # ! 5643: # GLOBAL VALUE FOR CDWRD PROCEDURE ! 5644: # ! 5645: cwcof: .long 0 # next word offset in current ccblk ! 5646: # ! 5647: # WORK AREAS FOR DATA FUNCTION (S$DAT) ! 5648: # ! 5649: datdv: .long 0 # save vrblk ptr for datatype name ! 5650: datxs: .long 0 # save initial stack pointer ! 5651: # ! 5652: # WORK AREAS FOR DEFINE FUNCTION (S$DEF) ! 5653: # ! 5654: deflb: .long 0 # save vrblk ptr for label ! 5655: defna: .long 0 # count function arguments ! 5656: defvr: .long 0 # save vrblk ptr for function name ! 5657: defxs: .long 0 # save initial stack pointer ! 5658: # ! 5659: # WORK AREAS FOR DUMPR PROCEDURE ! 5660: # ! 5661: dmarg: .long 0 # dump argument ! 5662: dmpkb: .long b$kvt # dummy kvblk for use in dumpr ! 5663: dmpkt: .long trbkv # kvvar trblk pointer ! 5664: dmpkn: .long 0 # keyword number (must follow dmpkb) ! 5665: dmpsa: .long 0 # preserve wa over prtvl call ! 5666: dmpsv: .long 0 # general scratch save ! 5667: dmvch: .long 0 # chain pointer for variable blocks ! 5668: dmpch: .long 0 # save sorted vrblk chain pointer ! 5669: # ! 5670: # GLOBAL LOCATIONS FOR DYNAMIC STORAGE POINTERS ! 5671: # ! 5672: dnamb: .long 0 # start of dynamic area ! 5673: dnamp: .long 0 # next available loc in dynamic area ! 5674: dname: .long 0 # end of available dynamic area ! 5675: # ! 5676: # WORK AREA FOR DTACH ! 5677: # ! 5678: dtcnb: .long 0 # name base ! 5679: dtcnm: .long 0 # name ptr ! 5680: # ! 5681: # WORK AREAS FOR DUPL FUNCTION (S$DUP) ! 5682: # ! 5683: dupsi: .long 0 # store integer string length ! 5684: # ! 5685: # WORK AREA FOR ENDFILE (S$ENF) ! 5686: # ! 5687: enfch: .long 0 # for iochn chain head ! 5688: # ! 5689: # WORK AREA FOR ERROR PROCESSING. ! 5690: # ! 5691: erich: .long 0 # copy error reports to int.chan if 1 ! 5692: erlst: .long 0 # for listr when errors go to int.ch. ! 5693: errft: .long 0 # fatal error flag ! 5694: errsp: .long 0 # error suppression flag ! 5695: #page ! 5696: # ! 5697: # DUMP AREA FOR ERTEX ! 5698: # ! 5699: ertwa: .long 0 # save wa ! 5700: ertwb: .long 0 # save wb ! 5701: # ! 5702: # GLOBAL VALUES FOR EVALI ! 5703: # ! 5704: evlin: .long p$len # dummy pattern block pcode ! 5705: evlis: .long 0 # pointer to subsequent node ! 5706: evliv: .long 0 # value of parameter ! 5707: # WORK AREA FOR EXPAN ! 5708: # ! 5709: expsv: .long 0 # save op dope vector pointer ! 5710: # ! 5711: # FLAG FOR SUPPRESSION OF EXECUTION STATS ! 5712: # ! 5713: exsts: .long 0 # suppress exec stats if set ! 5714: # ! 5715: # GLOBAL VALUES FOR EXFAL AND RETURN ! 5716: # ! 5717: flprt: .long 0 # location of fail offset for return ! 5718: flptr: .long 0 # location of failure offset on stack ! 5719: # ! 5720: # WORK AREAS FOR GBCOL PROCEDURE ! 5721: # ! 5722: gbcfl: .long 0 # garbage collector active flag ! 5723: gbclm: .long 0 # pointer to last move block (pass 3) ! 5724: gbcnm: .long 0 # dummy first move block ! 5725: gbcns: .long 0 # rest of dummy block (follows gbcnm) ! 5726: gbsva: .long 0 # save wa ! 5727: gbsvb: .long 0 # save wb ! 5728: gbsvc: .long 0 # save wc ! 5729: # ! 5730: # GLOBAL LOCATION TO COUNT GARBAGE COLLECTIONS (GBCOL) ! 5731: # ! 5732: gbcnt: .long 0 # count of garbage collections ! 5733: # ! 5734: # WORK AREAS FOR GTNVR PROCEDURE ! 5735: # ! 5736: gnvhe: .long 0 # ptr to end of hash chain ! 5737: gnvnw: .long 0 # number of words in string name ! 5738: gnvsa: .long 0 # save wa ! 5739: gnvsb: .long 0 # save wb ! 5740: gnvsp: .long 0 # pointer into vsrch table ! 5741: gnvst: .long 0 # pointer to chars of string ! 5742: # ! 5743: # GLOBAL VALUE FOR GTCOD AND GTEXP ! 5744: # ! 5745: gtcef: .long 0 # save fail ptr in case of error ! 5746: # ! 5747: # WORK AREAS FOR GTINT ! 5748: # ! 5749: gtina: .long 0 # save wa ! 5750: gtinb: .long 0 # save wb ! 5751: #page ! 5752: # ! 5753: # WORK AREAS FOR GTNUM PROCEDURE ! 5754: # ! 5755: gtnnf: .long 0 # zero/nonzero for result +/- ! 5756: gtnsi: .long 0 # general integer save ! 5757: gtndf: .long 0 # 0/1 for dec point so far no/yes ! 5758: gtnes: .long 0 # zero/nonzero exponent +/- ! 5759: gtnex: .long 0 # real exponent ! 5760: gtnsc: .long 0 # scale (places after point) ! 5761: gtnsr: .float 0f0.0 # general real save ! 5762: gtnrd: .long 0 # flag for ok real number ! 5763: # ! 5764: # WORK AREAS FOR GTPAT PROCEDURE ! 5765: # ! 5766: gtpsb: .long 0 # save wb ! 5767: # ! 5768: # WORK AREAS FOR GTSTG PROCEDURE ! 5769: # ! 5770: gtssf: .long 0 # 0/1 for result +/- ! 5771: gtsvc: .long 0 # save wc ! 5772: gtsvb: .long 0 # save wb ! 5773: gtswk: .long 0 # ptr to work area for gtstg ! 5774: gtses: .long 0 # char + or - for exponent +/- ! 5775: gtsrs: .float 0f0.0 # general real save ! 5776: # ! 5777: # GLOBAL LOCATIONS (CONSTANTS) FOR GTSTG PROCEDURE ! 5778: # ! 5779: gtsrn: .float 0f0.0 # rounding factor 0.5*10**-cfp$s ! 5780: gtssc: .float 0f0.0 # scaling value 10**cfp$s ! 5781: # ! 5782: # WORK AREAS FOR GTVAR PROCEDURE ! 5783: # ! 5784: gtvrc: .long 0 # save wc ! 5785: # ! 5786: # FLAG FOR HEADER PRINTING ! 5787: # ! 5788: headp: .long 0 # header printed flag ! 5789: # ! 5790: # GLOBAL VALUES FOR VARIABLE HASH TABLE ! 5791: # ! 5792: hshnb: .long 0 # number of hash buckets ! 5793: hshtb: .long 0 # pointer to start of vrblk hash tabl ! 5794: hshte: .long 0 # pointer past end of vrblk hash tabl ! 5795: # ! 5796: # WORK AREA FOR INIT ! 5797: # ! 5798: iniss: .long 0 # save subroutine stack ptr ! 5799: initr: .long 0 # save terminal flag ! 5800: # ! 5801: # SAVE AREA FOR INSBF ! 5802: # ! 5803: insab: .long 0 # entry wa + entry wb ! 5804: inssa: .long 0 # save entry wa ! 5805: inssb: .long 0 # save entry wb ! 5806: inssc: .long 0 # save entry wc ! 5807: # ! 5808: # WORK AREAS FOR IOPUT ! 5809: # ! 5810: ioptt: .long 0 # type of association ! 5811: #page ! 5812: # ! 5813: # GLOBAL VALUES FOR KEYWORD VALUES WHICH ARE STORED AS ONE ! 5814: # WORD INTEGERS. THESE VALUES MUST BE ASSEMBLED IN THE ! 5815: # FOLLOWING ORDER (AS DICTATED BY K$XXX DEFINITION VALUES). ! 5816: # ! 5817: kvabe: .long 0 # abend ! 5818: kvanc: .long 0 # anchor ! 5819: kvcas: .long 0 # case ! 5820: kvcod: .long 0 # code ! 5821: kvdmp: .long 0 # dump ! 5822: kverl: .long 0 # errlimit ! 5823: kvert: .long 0 # errtype ! 5824: kvftr: .long 0 # ftrace ! 5825: kvinp: .long 1 # input ! 5826: kvmxl: .long 5000 # maxlength ! 5827: kvoup: .long 1 # output ! 5828: kvpfl: .long 0 # profile ! 5829: kvtra: .long 0 # trace ! 5830: kvtrm: .long 0 # trim ! 5831: kvfnc: .long 0 # fnclevel ! 5832: kvlst: .long 0 # lastno ! 5833: kvstn: .long 0 # stno ! 5834: # ! 5835: # GLOBAL VALUES FOR OTHER KEYWORDS ! 5836: # ! 5837: kvalp: .long 0 # alphabet ! 5838: kvrtn: .long nulls # rtntype (scblk pointer) ! 5839: kvstl: .long 50000 # stlimit ! 5840: kvstc: .long 50000 # stcount (counts down from stlimit) ! 5841: # ! 5842: # WORK AREAS FOR LOAD FUNCTION ! 5843: # ! 5844: lodfn: .long 0 # pointer to vrblk for func name ! 5845: lodna: .long 0 # count number of arguments ! 5846: # ! 5847: # GLOBAL VALUES FOR LISTR PROCEDURE ! 5848: # ! 5849: lstlc: .long 0 # count lines on source list page ! 5850: lstnp: .long 0 # max number of lines on page ! 5851: lstpf: .long 1 # set nonzero if current image listed ! 5852: lstpg: .long 0 # current source list page number ! 5853: lstpo: .long 0 # offset to page nnn message ! 5854: lstsn: .long 0 # remember last stmnum listed ! 5855: # ! 5856: # MAXIMUM SIZE OF SPITBOL OBJECTS ! 5857: # ! 5858: mxlen: .long 0 # initialised by sysmx call ! 5859: # ! 5860: # EXECUTION CONTROL VARIABLE ! 5861: # ! 5862: noxeq: .long 0 # set non-zero to inhibit execution ! 5863: # ! 5864: # PROFILER GLOBAL VALUES AND WORK LOCATIONS ! 5865: # ! 5866: pfdmp: .long 0 # set non-0 if &profile set non-0 ! 5867: pffnc: .long 0 # set non-0 if funct just entered ! 5868: pfstm: .long 0 # to store starting time of stmt ! 5869: pfetm: .long 0 # to store ending time of stmt ! 5870: pfsvw: .long 0 # to save a w-reg ! 5871: pftbl: .long 0 # gets adrs of (imag) table base ! 5872: pfnte: .long 0 # nr of table entries ! 5873: pfste: .long 0 # gets int rep of table entry size ! 5874: # ! 5875: #page ! 5876: # ! 5877: # GLOBAL VALUES USED IN PATTERN MATCH ROUTINES ! 5878: # ! 5879: pmdfl: .long 0 # pattern assignment flag ! 5880: pmhbs: .long 0 # history stack base pointer ! 5881: pmssl: .long 0 # length of subject string in chars ! 5882: # ! 5883: # FLAGS USED FOR STANDARD FILE LISTING OPTIONS ! 5884: # ! 5885: prich: .long 0 # printer on interactive channel ! 5886: prstd: .long 0 # tested by prtpg ! 5887: prsto: .long 0 # standard listing option flag ! 5888: # ! 5889: # GLOBAL VALUE FOR PRTNM PROCEDURE ! 5890: # ! 5891: prnmv: .long 0 # vrblk ptr from last name search ! 5892: # ! 5893: # WORK AREAS FOR PRTNM PROCEDURE ! 5894: # ! 5895: prnsi: .long 0 # scratch integer loc ! 5896: # ! 5897: # WORK AREAS FOR PRTSN PROCEDURE ! 5898: # ! 5899: prsna: .long 0 # save wa ! 5900: # ! 5901: # GLOBAL VALUES FOR PRINT PROCEDURES ! 5902: # ! 5903: prbuf: .long 0 # ptr to print bfr in static ! 5904: precl: .long 0 # extended/compact listing flag ! 5905: prlen: .long 0 # length of print buffer in chars ! 5906: prlnw: .long 0 # length of print buffer in words ! 5907: profs: .long 0 # offset to next location in prbuf ! 5908: prtef: .long 0 # endfile flag ! 5909: # ! 5910: # WORK AREAS FOR PRTST PROCEDURE ! 5911: # ! 5912: prsva: .long 0 # save wa ! 5913: prsvb: .long 0 # save wb ! 5914: prsvc: .long 0 # save char counter ! 5915: # ! 5916: # WORK AREA FOR PRTNL ! 5917: # ! 5918: prtsa: .long 0 # save wa ! 5919: prtsb: .long 0 # save wb ! 5920: # ! 5921: # WORK AREA FOR PRTVL ! 5922: # ! 5923: prvsi: .long 0 # save idval ! 5924: # ! 5925: # WORK AREAS FOR PATTERN MATCH ROUTINES ! 5926: # ! 5927: psave: .long 0 # temporary save for current node ptr ! 5928: psavc: .long 0 # save cursor in p$spn, p$str ! 5929: #page ! 5930: # ! 5931: # AMOUNT OF MEMORY RESERVED FOR END OF EXECUTION ! 5932: # ! 5933: rsmem: .long 0 # reserve memory ! 5934: # ! 5935: # WORK AREAS FOR RETRN ROUTINE ! 5936: # ! 5937: rtnbp: .long 0 # to save a block pointer ! 5938: rtnfv: .long 0 # new function value (result) ! 5939: rtnsv: .long 0 # old function value (saved value) ! 5940: # ! 5941: # RELOCATABLE GLOBAL VALUES ! 5942: # ! 5943: # ALL THE POINTERS IN THIS SECTION CAN POINT TO BLOCKS IN ! 5944: # THE DYNAMIC STORAGE AREA AND MUST BE RELOCATED BY THE ! 5945: # GARBAGE COLLECTOR. THEY ARE IDENTIFIED BY R$XXX NAMES. ! 5946: # ! 5947: r$aaa: .long 0 # start of relocatable values ! 5948: r$arf: .long 0 # array block pointer for arref ! 5949: r$ccb: .long 0 # ptr to ccblk being built (cdwrd) ! 5950: r$cim: .long 0 # ptr to current compiler input str ! 5951: r$cmp: .long 0 # copy of r$cim used in cmpil ! 5952: r$cni: .long 0 # ptr to next compiler input string ! 5953: r$cnt: .long 0 # cdblk pointer for setexit continue ! 5954: r$cod: .long 0 # pointer to current cdblk or exblk ! 5955: r$ctp: .long 0 # ptr to current ctblk for patst ! 5956: r$ert: .long 0 # trblk pointer for errtype trace ! 5957: r$etx: .long nulls # pointer to errtext string ! 5958: r$exs: .long 0 # = save xl in expdm ! 5959: r$fcb: .long 0 # fcblk chain head ! 5960: r$fnc: .long 0 # trblk pointer for fnclevel trace ! 5961: r$gtc: .long 0 # keep code ptr for gtcod,gtexp ! 5962: r$io1: .long 0 # file arg1 for ioput ! 5963: r$io2: .long 0 # file arg2 for ioput ! 5964: r$iof: .long 0 # fcblk ptr or 0 ! 5965: r$ion: .long 0 # name base ptr ! 5966: r$iop: .long 0 # predecessor block ptr for ioput ! 5967: r$iot: .long 0 # trblk ptr for ioput ! 5968: r$pmb: .long 0 # buffer ptr in pattern match ! 5969: r$pms: .long 0 # subject string ptr in pattern match ! 5970: r$ra2: .long 0 # replace second argument last time ! 5971: r$ra3: .long 0 # replace third argument last time ! 5972: r$rpt: .long 0 # ptr to ctblk replace table last usd ! 5973: r$scp: .long 0 # save pointer from last scane call ! 5974: r$sxl: .long 0 # preserve xl in sortc ! 5975: r$sxr: .long 0 # preserve xr in sorta/sortc ! 5976: r$stc: .long 0 # trblk pointer for stcount trace ! 5977: r$stl: .long 0 # source listing sub-title ! 5978: r$sxc: .long 0 # code (cdblk) ptr for setexit trap ! 5979: r$ttl: .long nulls # source listing title ! 5980: r$xsc: .long 0 # string pointer for xscan ! 5981: #page ! 5982: # ! 5983: # THE REMAINING POINTERS IN THIS LIST ARE USED TO POINT ! 5984: # TO FUNCTION BLOCKS FOR NORMALLY UNDEFINED OPERATORS. ! 5985: # ! 5986: r$uba: .long stndo # binary at ! 5987: r$ubm: .long stndo # binary ampersand ! 5988: r$ubn: .long stndo # binary number sign ! 5989: r$ubp: .long stndo # binary percent ! 5990: r$ubt: .long stndo # binary not ! 5991: r$uub: .long stndo # unary vertical bar ! 5992: r$uue: .long stndo # unary equal ! 5993: r$uun: .long stndo # unary number sign ! 5994: r$uup: .long stndo # unary percent ! 5995: r$uus: .long stndo # unary slash ! 5996: r$uux: .long stndo # unary exclamation ! 5997: r$yyy: .long 0 # last relocatable location ! 5998: # ! 5999: # WORK AREAS FOR SUBSTR FUNCTION (S$SUB) ! 6000: # ! 6001: sbssv: .long 0 # save third argument ! 6002: # ! 6003: # GLOBAL LOCATIONS USED IN SCAN PROCEDURE ! 6004: # ! 6005: scnbl: .long 0 # set non-zero if scanned past blanks ! 6006: scncc: .long 0 # non-zero to scan control card name ! 6007: scngo: .long 0 # set non-zero to scan goto field ! 6008: scnil: .long 0 # length of current input image ! 6009: scnpt: .long 0 # pointer to next location in r$cim ! 6010: scnrs: .long 0 # set non-zero to signal rescan ! 6011: scntp: .long 0 # save syntax type from last call ! 6012: # ! 6013: # WORK AREAS FOR SCAN PROCEDURE ! 6014: # ! 6015: scnsa: .long 0 # save wa ! 6016: scnsb: .long 0 # save wb ! 6017: scnsc: .long 0 # save wc ! 6018: scnse: .long 0 # start of current element ! 6019: scnof: .long 0 # save offset ! 6020: #page ! 6021: # ! 6022: # WORK AREA USED BY SORTA, SORTC, SORTF, SORTH ! 6023: # ! 6024: srtdf: .long 0 # datatype field name ! 6025: srtfd: .long 0 # found dfblk address ! 6026: srtff: .long 0 # found field name ! 6027: srtfo: .long 0 # offset to field name ! 6028: srtnr: .long 0 # number of rows ! 6029: srtof: .long 0 # offset within row to sort key ! 6030: srtrt: .long 0 # root offset ! 6031: srts1: .long 0 # save offset 1 ! 6032: srts2: .long 0 # save offset 2 ! 6033: srtsc: .long 0 # save wc ! 6034: srtsf: .long 0 # sort array first row offset ! 6035: srtsn: .long 0 # save n ! 6036: srtso: .long 0 # offset to a(0) ! 6037: srtsr: .long 0 # 0 , non-zero for sort, rsort ! 6038: srtst: .long 0 # stride from one row to next ! 6039: srtwc: .long 0 # dump wc ! 6040: # ! 6041: # GLOBAL VALUE FOR INDICATING STAGE (SEE ERROR SECTION) ! 6042: # ! 6043: stage: .long 0 # initial value = initial compile ! 6044: # ! 6045: # GLOBAL VALUES DEFINING EXTENT OF STATIC AREA (ALOST) ! 6046: # ! 6047: statb: .long 0 # start of static area ! 6048: state: .long 0 # end of static area ! 6049: #page ! 6050: # ! 6051: # GLOBAL STACK POINTER ! 6052: # ! 6053: stbas: .long 0 # pointer past stack base ! 6054: # ! 6055: # WORK AREAS FOR STOPR ROUTINE ! 6056: # ! 6057: stpsi: .long 0 # save value of stcount ! 6058: stpti: .long 0 # save time elapsed ! 6059: # ! 6060: # GLOBAL VALUES FOR SETEXIT FUNCTION (S$STX) ! 6061: # ! 6062: stxof: .long 0 # failure offset ! 6063: stxvr: .long nulls # vrblk pointer or null ! 6064: # ! 6065: # WORK AREAS FOR TFIND PROCEDURE ! 6066: # ! 6067: tfnsi: .long 0 # number of headers ! 6068: # ! 6069: # GLOBAL VALUE FOR TIME KEEPING ! 6070: # ! 6071: timsx: .long 0 # time at start of execution ! 6072: timup: .long 0 # set when time up occurs ! 6073: # ! 6074: # WORK AREAS FOR XSCAN PROCEDURE ! 6075: # ! 6076: xscrt: .long 0 # save return code ! 6077: xscwb: .long 0 # save register wb ! 6078: # ! 6079: # GLOBAL VALUES FOR XSCAN AND XSCNI PROCEDURES ! 6080: # ! 6081: xsofs: .long 0 # offset to current location in r$xsc ! 6082: # ! 6083: # LABEL TO MARK END OF WORK AREA ! 6084: # ! 6085: yyyyy: .long 0 ! 6086: #title s p i t b o l -- initialization ! 6087: # ! 6088: # INITIALISATION ! 6089: # THE FOLLOWING SECTION RECEIVES CONTROL FROM THE SYSTEM ! 6090: # AT THE START OF A RUN WITH THE REGISTERS SET AS FOLLOWS. ! 6091: # ! 6092: # (XS) POINTS PAST STACK BASE ! 6093: # (XR) POINTS TO FIRST WORD OF DATA AREA ! 6094: # (XL) POINTS TO LAST WORD OF DATA AREA ! 6095: # ! 6096: .text 0 ! 6097: .globl sec04 ! 6098: sec04: ! 6099: #sec # start of program section ! 6100: jsb systm # initialise timer ! 6101: # ! 6102: # INITIALISE WORK AREA (ESSENTIAL FOR BATCHED RUNS) ! 6103: # ! 6104: movl r9,r7 # preserve xr ! 6105: movl $yyyyy,r6 # point to end of work area ! 6106: subl2 $aaaaa,r6 # get length of work area ! 6107: ashl $-2,r6,r6 # convert to words ! 6108: # count for loop ! 6109: movl $aaaaa,r9 # set up index register ! 6110: # ! 6111: # CLEAR WORK SPACE ! 6112: # ! 6113: ini01: clrl (r9)+ # clear a word ! 6114: sobgtr r6,ini01 # loop till done ! 6115: movl $stndo,r6 # undefined operators pointer ! 6116: movl $r$yyy,r8 # point to table end ! 6117: subl2 $r$uba,r8 # length of undef. operators table ! 6118: ashl $-2,r8,r8 # convert to words ! 6119: # loop counter ! 6120: movl $r$uba,r9 # set up xr ! 6121: # ! 6122: # SET CORRECT VALUE INTO UNDEFINED OPERATORS TABLE ! 6123: # ! 6124: ini02: movl r6,(r9)+ # store value ! 6125: sobgtr r8,ini02 # loop till all done ! 6126: movl $num01,r6 # get a 1 ! 6127: movl r6,cmpsn # statement no ! 6128: movl r6,cswfl # nofail ! 6129: movl r6,cswls # list ! 6130: movl r6,kvinp # input ! 6131: movl r6,kvoup # output ! 6132: movl r6,lstpf # nothing for listr yet ! 6133: movl $iniln,r6 # input image length ! 6134: movl r6,cswin # -in72 ! 6135: movl $b$kvt,dmpkb # dump ! 6136: movl $trbkv,dmpkt # dump ! 6137: movl $p$len,evlin # eval ! 6138: #page ! 6139: movl $nulls,r6 # get nullstring pointer ! 6140: movl r6,kvrtn # return ! 6141: movl r6,r$etx # errtext ! 6142: movl r6,r$ttl # title for listing ! 6143: movl r6,stxvr # setexit ! 6144: movl r5,timsx # store time in correct place ! 6145: movl stlim,r5 # get default stlimit ! 6146: movl r5,kvstl # statement limit ! 6147: movl r5,kvstc # statement count ! 6148: movl r7,statb # store start adrs of static ! 6149: movl $4*e$srs,rsmem # reserve memory ! 6150: movl sp,stbas # store stack base ! 6151: #sss iniss # save s-r stack ptr ! 6152: # ! 6153: # NOW CONVERT FREE STORE PERCENTAGE TO A SUITABLE FACTOR ! 6154: # FOR EASY TESTING IN ALLOC ROUTINE. ! 6155: # ! 6156: movl intvh,r5 # get 100 ! 6157: divl2 alfsp,r5 # form 100 / alfsp ! 6158: movl r5,alfsf # store the factor ! 6159: # ! 6160: # INITIALIZE VALUES FOR REAL CONVERSION ROUTINE ! 6161: # ! 6162: movl $cfp$s,r7 # load counter for significant digits ! 6163: movf reav1,r2 # load 1.0 ! 6164: # ! 6165: # LOOP TO COMPUTE 10**(MAX NUMBER SIGNIFICANT DIGITS) ! 6166: # ! 6167: ini03: mulf2 reavt,r2 # * 10.0 ! 6168: sobgtr r7,ini03 # loop till done ! 6169: movf r2,gtssc # store 10**(max sig digits) ! 6170: movf reap5,r2 # load 0.5 ! 6171: divf2 gtssc,r2 # compute 0.5*10**(max sig digits) ! 6172: movf r2,gtsrn # store as rounding bias ! 6173: clrl r8 # set to read parameters ! 6174: jsb prpar # read them ! 6175: #page ! 6176: # ! 6177: # NOW COMPUTE STARTING ADDRESS FOR DYNAMIC STORE AND IF ! 6178: # NECESSARY REQUEST MORE MEMORY. ! 6179: # ! 6180: subl2 $4*e$srs,r10 # allow for reserve memory ! 6181: movl prlen,r6 # get print buffer length ! 6182: addl2 $cfp$a,r6 # add no. of chars in alphabet ! 6183: addl2 $nstmx,r6 # add chars for gtstg bfr ! 6184: movab 3+(4*8)(r6),r6 # convert to bytes, allowing a margin ! 6185: bicl2 $3,r6 ! 6186: movl statb,r9 # point to static base ! 6187: addl2 r6,r9 # increment for above buffers ! 6188: addl2 $4*e$hnb,r9 # increment for hash table ! 6189: addl2 $4*e$sts,r9 # bump for initial static block ! 6190: jsb sysmx # get mxlen ! 6191: movl r6,kvmxl # provisionally store as maxlngth ! 6192: movl r6,mxlen # and as mxlen ! 6193: cmpl r9,r6 # skip if static hi exceeds mxlen ! 6194: bgtru ini06 ! 6195: movl r6,r9 # use mxlen instead ! 6196: addl2 $4,r9 # make bigger than mxlen ! 6197: # ! 6198: # HERE TO STORE VALUES WHICH MARK INITIAL DIVISION ! 6199: # OF DATA AREA INTO STATIC AND DYNAMIC ! 6200: # ! 6201: ini06: movl r9,dnamb # dynamic base adrs ! 6202: movl r9,dnamp # dynamic ptr ! 6203: tstl r6 # skip if non-zero mxlen ! 6204: bnequ ini07 ! 6205: subl2 $4,r9 # point a word in front ! 6206: movl r9,kvmxl # use as maxlngth ! 6207: movl r9,mxlen # and as mxlen ! 6208: #page ! 6209: # ! 6210: # LOOP HERE IF NECESSARY TILL ENOUGH MEMORY OBTAINED ! 6211: # SO THAT DNAME IS ABOVE DNAMB ! 6212: # ! 6213: ini07: movl r10,dname # store dynamic end address ! 6214: cmpl dnamb,r10 # skip if high enough ! 6215: blssu ini09 ! 6216: jsb sysmm # request more memory ! 6217: moval 0[r9],r9 # get as baus (sgd05) ! 6218: addl2 r9,r10 # bump by amount obtained ! 6219: tstl r9 # try again ! 6220: bnequ ini07 ! 6221: movl $endmo,r9 # point to failure message ! 6222: movl endml,r6 # message length ! 6223: jsb syspr # print it (prtst not yet usable) ! 6224: .long invalid$ # should not fail ! 6225: jsb sysej # pack up (stopr not yet usable) ! 6226: # ! 6227: # INITIALISE PRINT BUFFER WITH BLANK WORDS ! 6228: # ! 6229: ini09: movl prlen,r8 # no. of chars in print bfr ! 6230: movl statb,r9 # point to static again ! 6231: movl r9,prbuf # print bfr is put at static start ! 6232: movl $b$scl,(r9)+ # store string type code ! 6233: movl r8,(r9)+ # and string length ! 6234: movab 3+(4*0)(r8),r8 # get number of words in buffer ! 6235: ashl $-2,r8,r8 ! 6236: movl r8,prlnw # store for buffer clear ! 6237: # words to clear ! 6238: # ! 6239: # LOOP TO CLEAR BUFFER ! 6240: # ! 6241: ini10: movl nullw,(r9)+ # store blank ! 6242: sobgtr r8,ini10 # loop ! 6243: # ! 6244: # INITIALIZE NUMBER OF HASH HEADERS ! 6245: # ! 6246: movl $e$hnb,r6 # get number of hash headers ! 6247: movl r6,r5 # convert to integer ! 6248: movl r5,hshnb # store for use by gtnvr procedure ! 6249: # counter for clearing hash table ! 6250: movl r9,hshtb # pointer to hash table ! 6251: # ! 6252: # LOOP TO CLEAR HASH TABLE ! 6253: # ! 6254: ini11: clrl (r9)+ # blank a word ! 6255: sobgtr r6,ini11 # loop ! 6256: movl r9,hshte # end of hash table adrs is kept ! 6257: # ! 6258: # ALLOCATE WORK AREA FOR GTSTG CONVERSION PROCEDURE ! 6259: # ! 6260: movl $nstmx,r6 # get max num chars in output number ! 6261: movab 3+(4*scsi$)(r6),r6 # no of bytes needed ! 6262: bicl2 $3,r6 ! 6263: movl r9,gtswk # store bfr adrs ! 6264: addl2 r6,r9 # bump for work bfr ! 6265: #page ! 6266: # ! 6267: # BUILD ALPHABET STRING FOR ALPHABET KEYWORD AND REPLACE ! 6268: # ! 6269: movl r9,kvalp # save alphabet pointer ! 6270: movl $b$scl,(r9) # string blk type ! 6271: movl $cfp$a,r8 # no of chars in alphabet ! 6272: movl r8,4*sclen(r9) # store as string length ! 6273: movl r8,r7 # copy char count ! 6274: movab 3+(4*scsi$)(r7),r7 # no. of bytes needed ! 6275: bicl2 $3,r7 ! 6276: addl2 r9,r7 # current end address for static ! 6277: movl r7,state # store static end adrs ! 6278: # loop counter ! 6279: movab cfp$f(r9),r9 # point to chars of string ! 6280: clrl r7 # set initial character value ! 6281: # ! 6282: # LOOP TO ENTER CHARACTER CODES IN ORDER ! 6283: # ! 6284: ini12: movb r7,(r9)+ # store next code ! 6285: incl r7 # bump code value ! 6286: sobgtr r8,ini12 # loop till all stored ! 6287: #csc r9 # complete store characters ! 6288: # ! 6289: # INITIALIZE VARIABLE BLOCKS FOR INPUT AND OUTPUT ! 6290: # ! 6291: movl $v$inp,r10 # point to string /input/ ! 6292: movl $trtin,r7 # trblk type for input ! 6293: jsb inout # perform input association ! 6294: movl $v$oup,r10 # point to string /output/ ! 6295: movl $trtou,r7 # trblk type for output ! 6296: jsb inout # perform output association ! 6297: movl initr,r8 # terminal flag ! 6298: tstl r8 # skip if no terminal ! 6299: beqlu ini13 ! 6300: jsb prpar # associate terminal ! 6301: #page ! 6302: # ! 6303: # CHECK FOR EXPIRY DATE ! 6304: # ! 6305: ini13: jsb sysdc # call date check ! 6306: movl sp,flptr # in case stack overflows in compiler ! 6307: # ! 6308: # NOW COMPILE SOURCE INPUT CODE ! 6309: # ! 6310: jsb cmpil # call compiler ! 6311: movl r9,r$cod # set ptr to first code block ! 6312: movl $nulls,r$ttl # forget title (reg04) ! 6313: movl $nulls,r$stl # forget sub-title (reg04) ! 6314: clrl r$cim # forget compiler input image ! 6315: clrl r10 # clear dud value ! 6316: clrl r7 # dont shift dynamic store up ! 6317: jsb gbcol # clear garbage left from compile ! 6318: tstl cpsts # skip if no listing of comp stats ! 6319: beqlu 0f ! 6320: jmp inix0 ! 6321: 0: ! 6322: jsb prtpg # eject page ! 6323: # ! 6324: # PRINT COMPILE STATISTICS ! 6325: # ! 6326: movl dnamp,r6 # next available loc ! 6327: subl2 statb,r6 # minus start ! 6328: ashl $-2,r6,r6 # convert to words ! 6329: movl r6,r5 # convert to integer ! 6330: movl $encm1,r9 # point to /memory used (words)/ ! 6331: jsb prtmi # print message ! 6332: movl dname,r6 # end of memory ! 6333: subl2 dnamp,r6 # minus next available loc ! 6334: ashl $-2,r6,r6 # convert to words ! 6335: movl r6,r5 # convert to integer ! 6336: movl $encm2,r9 # point to /memory available (words)/ ! 6337: jsb prtmi # print line ! 6338: movl cmerc,r5 # get count of errors as integer ! 6339: movl $encm3,r9 # point to /compile errors/ ! 6340: jsb prtmi # print it ! 6341: movl gbcnt,r5 # garbage collection count ! 6342: subl2 intv1,r5 # adjust for unavoidable collect ! 6343: movl $stpm5,r9 # point to /storage regenerations/ ! 6344: jsb prtmi # print gbcol count ! 6345: jsb systm # get time ! 6346: subl2 timsx,r5 # get compilation time ! 6347: movl $encm4,r9 # point to compilation time (msec)/ ! 6348: jsb prtmi # print message ! 6349: addl2 $num05,lstlc # bump line count ! 6350: tstl headp # no eject if nothing printed (sdg11) ! 6351: bnequ 0f ! 6352: jmp inix0 ! 6353: 0: ! 6354: jsb prtpg # eject printer ! 6355: #page ! 6356: # ! 6357: # PREPARE NOW TO START EXECUTION ! 6358: # ! 6359: # SET DEFAULT INPUT RECORD LENGTH ! 6360: # ! 6361: inix0: cmpl cswin,$iniln # skip if not default -in72 used ! 6362: bgtru inix1 ! 6363: movl $inils,cswin # else use default record length ! 6364: # ! 6365: # RESET TIMER ! 6366: # ! 6367: inix1: jsb systm # get time again ! 6368: movl r5,timsx # store for end run processing ! 6369: addl2 cswex,noxeq # add -noexecute flag ! 6370: tstl noxeq # jump if execution suppressed ! 6371: bnequ inix2 ! 6372: clrl gbcnt # initialise collect count ! 6373: jsb sysbx # call before starting execution ! 6374: # ! 6375: # MERGE WHEN LISTING FILE SET FOR EXECUTION ! 6376: # ! 6377: iniy0: movl sp,headp # mark headers out regardless ! 6378: clrl -(sp) # set failure location on stack ! 6379: movl sp,flptr # save ptr to failure offset word ! 6380: movl r$cod,r9 # load ptr to entry code block ! 6381: movl $stgxt,stage # set stage for execute time ! 6382: movl cmpsn,pfnte # copy stmts compiled count in case ! 6383: jsb systm # time yet again ! 6384: movl r5,pfstm ! 6385: movl (r9),r11 # start xeq with first statement ! 6386: jmp (r11) ! 6387: # ! 6388: # HERE IF EXECUTION IS SUPPRESSED ! 6389: # ! 6390: inix2: jsb prtnl # print a blank line ! 6391: movl $encm5,r9 # point to /execution suppressed/ ! 6392: jsb prtst # print string ! 6393: jsb prtnl # output line ! 6394: clrl r6 # set abend value to zero ! 6395: movl $nini9,r7 # set special code value ! 6396: jsb sysej # end of job, exit to system ! 6397: #title s p i t b o l -- snobol4 operator routines ! 6398: # ! 6399: # THIS SECTION INCLUDES ALL ROUTINES WHICH CAN BE ACCESSED ! 6400: # DIRECTLY FROM THE GENERATED CODE EXCEPT SYSTEM FUNCTIONS. ! 6401: # ! 6402: # ALL ROUTINES IN THIS SECTION START WITH A LABEL OF THE ! 6403: # FORM O$XXX WHERE XXX IS THREE LETTERS. THE GENERATED CODE ! 6404: # CONTAINS A POINTER TO THE APPROPRIATE ENTRY LABEL. ! 6405: # ! 6406: # SINCE THE GENERAL FORM OF THE GENERATED CODE CONSISTS OF ! 6407: # POINTERS TO BLOCKS WHOSE FIRST WORD IS THE ADDRESS OF THE ! 6408: # ACTUAL ENTRY POINT LABEL (O$XXX). ! 6409: # ! 6410: # THESE ROUTINES ARE IN ALPHABETICAL ORDER BY THEIR ! 6411: # ENTRY LABEL NAMES (I.E. BY THE XXX OF THE O$XXX NAME) ! 6412: # ! 6413: # THESE ROUTINES RECEIVE CONTROL AS FOLLOWS ! 6414: # ! 6415: # (CP) POINTER TO NEXT CODE WORD ! 6416: # (XS) CURRENT STACK POINTER ! 6417: #page ! 6418: # ! 6419: # BINARY PLUS (ADDITION) ! 6420: # ! 6421: o$add: # entry point ! 6422: jsb arith # fetch arithmetic operands ! 6423: .long er_001 # addition left operand is not numeric ! 6424: .long er_002 # addition right operand is not numeric ! 6425: .long oadd1 # jump if real operands ! 6426: # ! 6427: # HERE TO ADD TWO INTEGERS ! 6428: # ! 6429: addl2 4*icval(r10),r5 # add right operand to left ! 6430: bvs 0f ! 6431: jmp exint ! 6432: 0: ! 6433: jmp er_003 # addition caused integer overflow ! 6434: # ! 6435: # HERE TO ADD TWO REALS ! 6436: # ! 6437: oadd1: addf2 4*rcval(r10),r2 # add right operand to left ! 6438: bvs 0f ! 6439: jmp exrea ! 6440: 0: ! 6441: jmp er_261 # addition caused real overflow ! 6442: #page ! 6443: # ! 6444: # UNARY PLUS (AFFIRMATION) ! 6445: # ! 6446: o$aff: # entry point ! 6447: movl (sp)+,r9 # load operand ! 6448: jsb gtnum # convert to numeric ! 6449: .long er_004 # affirmation operand is not numeric ! 6450: jmp exixr # return if converted to numeric ! 6451: #page ! 6452: # ! 6453: # BINARY BAR (ALTERNATION) ! 6454: # ! 6455: o$alt: # entry point ! 6456: movl (sp)+,r9 # load right operand ! 6457: jsb gtpat # convert to pattern ! 6458: .long er_005 # alternation right operand is not pattern ! 6459: # ! 6460: # MERGE HERE FROM SPECIAL (LEFT ALTERNATION) CASE ! 6461: # ! 6462: oalt1: movl $p$alt,r7 # set pcode for alternative node ! 6463: jsb pbild # build alternative node ! 6464: movl r9,r10 # save address of alternative node ! 6465: movl (sp)+,r9 # load left operand ! 6466: jsb gtpat # convert to pattern ! 6467: .long er_006 # alternation left operand is not pattern ! 6468: cmpl r9,$p$alt # jump if left arg is alternation ! 6469: beqlu oalt2 ! 6470: movl r9,4*pthen(r10) # set left operand as successor ! 6471: movl r10,r9 # move result to proper register ! 6472: jmp exixr # jump for next code word ! 6473: # ! 6474: # COME HERE IF LEFT ARGUMENT IS ITSELF AN ALTERNATION ! 6475: # ! 6476: # THE RESULT IS MORE EFFICIENT IF WE MAKE THE REPLACEMENT ! 6477: # ! 6478: # (A / B) / C = A / (B / C) ! 6479: # ! 6480: oalt2: movl 4*parm1(r9),4*pthen(r10) # build the (b / c) node ! 6481: movl 4*pthen(r9),-(sp)# set a as new left arg ! 6482: movl r10,r9 # set (b / c) as new right arg ! 6483: jmp oalt1 # merge back to build a / (b / c) ! 6484: #page ! 6485: # ! 6486: # ARRAY REFERENCE (MULTIPLE SUBSCRIPTS, BY NAME) ! 6487: # ! 6488: o$amn: # entry point ! 6489: movl (r3)+,r9 # load number of subscripts ! 6490: movl r9,r7 # set flag for by name ! 6491: jmp arref # jump to array reference routine ! 6492: #page ! 6493: # ! 6494: # ARRAY REFERENCE (MULTIPLE SUBSCRIPTS, BY VALUE) ! 6495: # ! 6496: o$amv: # entry point ! 6497: movl (r3)+,r9 # load number of subscripts ! 6498: clrl r7 # set flag for by value ! 6499: jmp arref # jump to array reference routine ! 6500: #page ! 6501: # ! 6502: # ARRAY REFERENCE (ONE SUBSCRIPT, BY NAME) ! 6503: # ! 6504: o$aon: # entry point ! 6505: movl (sp),r9 # load subscript value ! 6506: movl 4*1(sp),r10 # load array value ! 6507: movl (r10),r6 # load first word of array operand ! 6508: cmpl r6,$b$vct # jump if vector reference ! 6509: beqlu oaon2 ! 6510: cmpl r6,$b$tbt # jump if table reference ! 6511: beqlu oaon3 ! 6512: # ! 6513: # HERE TO USE CENTRAL ARRAY REFERENCE ROUTINE ! 6514: # ! 6515: oaon1: movl $num01,r9 # set number of subscripts to one ! 6516: movl r9,r7 # set flag for by name ! 6517: jmp arref # jump to array reference routine ! 6518: # ! 6519: # HERE IF WE HAVE A VECTOR REFERENCE ! 6520: # ! 6521: oaon2: cmpl (r9),$b$icl # use long routine if not integer ! 6522: bnequ oaon1 ! 6523: movl 4*icval(r9),r5 # load integer subscript value ! 6524: movl r5,r6 # copy as address int, fail if ovflo ! 6525: bgeq 0f ! 6526: jmp exfal ! 6527: 0: ! 6528: tstl r6 # fail if zero ! 6529: bnequ 0f ! 6530: jmp exfal ! 6531: 0: ! 6532: addl2 $vcvlb,r6 # compute offset in words ! 6533: moval 0[r6],r6 # convert to bytes ! 6534: movl r6,(sp) # complete name on stack ! 6535: cmpl r6,4*vclen(r10) # exit if subscript not too large ! 6536: bgequ 0f ! 6537: jmp exits ! 6538: 0: ! 6539: jmp exfal # else fail ! 6540: # ! 6541: # HERE FOR TABLE REFERENCE ! 6542: # ! 6543: oaon3: movl sp,r7 # set flag for name reference ! 6544: jsb tfind # locate/create table element ! 6545: .long exfal # fail if access fails ! 6546: movl r10,4*1(sp) # store name base on stack ! 6547: movl r6,(sp) # store name offset on stack ! 6548: jmp exits # exit with result on stack ! 6549: #page ! 6550: # ! 6551: # ARRAY REFERENCE (ONE SUBSCRIPT, BY VALUE) ! 6552: # ! 6553: o$aov: # entry point ! 6554: movl (sp)+,r9 # load subscript value ! 6555: movl (sp)+,r10 # load array value ! 6556: movl (r10),r6 # load first word of array operand ! 6557: cmpl r6,$b$vct # jump if vector reference ! 6558: beqlu oaov2 ! 6559: cmpl r6,$b$tbt # jump if table reference ! 6560: beqlu oaov3 ! 6561: # ! 6562: # HERE TO USE CENTRAL ARRAY REFERENCE ROUTINE ! 6563: # ! 6564: oaov1: movl r10,-(sp) # restack array value ! 6565: movl r9,-(sp) # restack subscript ! 6566: movl $num01,r9 # set number of subscripts to one ! 6567: clrl r7 # set flag for value call ! 6568: jmp arref # jump to array reference routine ! 6569: # ! 6570: # HERE IF WE HAVE A VECTOR REFERENCE ! 6571: # ! 6572: oaov2: cmpl (r9),$b$icl # use long routine if not integer ! 6573: bnequ oaov1 ! 6574: movl 4*icval(r9),r5 # load integer subscript value ! 6575: movl r5,r6 # move as one word int, fail if ovflo ! 6576: bgeq 0f ! 6577: jmp exfal ! 6578: 0: ! 6579: tstl r6 # fail if zero ! 6580: bnequ 0f ! 6581: jmp exfal ! 6582: 0: ! 6583: addl2 $vcvlb,r6 # compute offset in words ! 6584: moval 0[r6],r6 # convert to bytes ! 6585: cmpl r6,4*vclen(r10) # fail if subscript too large ! 6586: blssu 0f ! 6587: jmp exfal ! 6588: 0: ! 6589: jsb acess # access value ! 6590: .long exfal # fail if access fails ! 6591: jmp exixr # else return value to caller ! 6592: # ! 6593: # HERE FOR TABLE REFERENCE BY VALUE ! 6594: # ! 6595: oaov3: clrl r7 # set flag for value reference ! 6596: jsb tfind # call table search routine ! 6597: .long exfal # fail if access fails ! 6598: jmp exixr # exit with result in xr ! 6599: #page ! 6600: # ! 6601: # ASSIGNMENT ! 6602: # ! 6603: o$ass: # entry point ! 6604: # ! 6605: # O$RPL (PATTERN REPLACEMENT) MERGES HERE ! 6606: # ! 6607: oass0: movl (sp)+,r7 # load value to be assigned ! 6608: movl (sp)+,r6 # load name offset ! 6609: movl (sp),r10 # load name base ! 6610: movl r7,(sp) # store assigned value as result ! 6611: jsb asign # perform assignment ! 6612: .long exfal # fail if assignment fails ! 6613: jmp exits # exit with result on stack ! 6614: #page ! 6615: # ! 6616: # COMPILATION ERROR ! 6617: # ! 6618: o$cer: # entry point ! 6619: jmp er_007 # compilation error encountered during execution ! 6620: #page ! 6621: # ! 6622: # UNARY AT (CURSOR ASSIGNMENT) ! 6623: # ! 6624: o$cas: # entry point ! 6625: movl (sp)+,r8 # load name offset (parm2) ! 6626: movl (sp)+,r9 # load name base (parm1) ! 6627: movl $p$cas,r7 # set pcode for cursor assignment ! 6628: jsb pbild # build node ! 6629: jmp exixr # jump for next code word ! 6630: #page ! 6631: # ! 6632: # CONCATENATION ! 6633: # ! 6634: o$cnc: # entry point ! 6635: movl (sp),r9 # load right argument ! 6636: cmpl r9,$nulls # jump if right arg is null ! 6637: bnequ 0f ! 6638: jmp ocnc3 ! 6639: 0: ! 6640: movl 4*1(sp),r10 # load left argument ! 6641: cmpl r10,$nulls # jump if left argument is null ! 6642: bnequ 0f ! 6643: jmp ocnc4 ! 6644: 0: ! 6645: movl $b$scl,r6 # get constant to test for string ! 6646: cmpl r6,(r10) # jump if left arg not a string ! 6647: beqlu 0f ! 6648: jmp ocnc2 ! 6649: 0: ! 6650: cmpl r6,(r9) # jump if right arg not a string ! 6651: beqlu 0f ! 6652: jmp ocnc2 ! 6653: 0: ! 6654: # ! 6655: # MERGE HERE TO CONCATENATE TWO STRINGS ! 6656: # ! 6657: ocnc1: movl 4*sclen(r10),r6 # load left argument length ! 6658: addl2 4*sclen(r9),r6 # compute result length ! 6659: jsb alocs # allocate scblk for result ! 6660: movl r9,4*1(sp) # store result ptr over left argument ! 6661: movab cfp$f(r9),r9 # prepare to store chars of result ! 6662: movl 4*sclen(r10),r6 # get number of chars in left arg ! 6663: movab cfp$f(r10),r10 # prepare to load left arg chars ! 6664: jsb sbmvc # move characters of left argument ! 6665: movl (sp)+,r10 # load right arg pointer, pop stack ! 6666: movl 4*sclen(r10),r6 # load number of chars in right arg ! 6667: movab cfp$f(r10),r10 # prepare to load right arg chars ! 6668: jsb sbmvc # move characters of right argument ! 6669: jmp exits # exit with result on stack ! 6670: # ! 6671: # COME HERE IF ARGUMENTS ARE NOT BOTH STRINGS ! 6672: # ! 6673: ocnc2: jsb gtstg # convert right arg to string ! 6674: .long ocnc5 # jump if right arg is not string ! 6675: movl r9,r10 # save right arg ptr ! 6676: jsb gtstg # convert left arg to string ! 6677: .long ocnc6 # jump if left arg is not a string ! 6678: movl r9,-(sp) # stack left argument ! 6679: movl r10,-(sp) # stack right argument ! 6680: movl r9,r10 # move left arg to proper reg ! 6681: movl (sp),r9 # move right arg to proper reg ! 6682: jmp ocnc1 # merge back to concatenate strings ! 6683: #page ! 6684: # ! 6685: # CONCATENATION (CONTINUED) ! 6686: # ! 6687: # COME HERE FOR NULL RIGHT ARGUMENT ! 6688: # ! 6689: ocnc3: addl2 $4,sp # remove right arg from stack ! 6690: jmp exits # return with left argument on stack ! 6691: # ! 6692: # HERE FOR NULL LEFT ARGUMENT ! 6693: # ! 6694: ocnc4: addl2 $4,sp # unstack one argument ! 6695: movl r9,(sp) # store right argument ! 6696: jmp exits # exit with result on stack ! 6697: # ! 6698: # HERE IF RIGHT ARGUMENT IS NOT A STRING ! 6699: # ! 6700: ocnc5: movl r9,r10 # move right argument ptr ! 6701: movl (sp)+,r9 # load left arg pointer ! 6702: # ! 6703: # MERGE HERE WHEN LEFT ARGUMENT IS NOT A STRING ! 6704: # ! 6705: ocnc6: jsb gtpat # convert left arg to pattern ! 6706: .long er_008 # concatenation left opnd is not string or pattern ! 6707: movl r9,-(sp) # save result on stack ! 6708: movl r10,r9 # point to right operand ! 6709: jsb gtpat # convert to pattern ! 6710: .long er_009 # concatenation right opd is not string or pattern ! 6711: movl r9,r10 # move for pconc ! 6712: movl (sp)+,r9 # reload left operand ptr ! 6713: jsb pconc # concatenate patterns ! 6714: jmp exixr # exit with result in xr ! 6715: #page ! 6716: # ! 6717: # COMPLEMENTATION ! 6718: # ! 6719: o$com: # entry point ! 6720: movl (sp)+,r9 # load operand ! 6721: movl (r9),r6 # load type word ! 6722: # ! 6723: # MERGE BACK HERE AFTER CONVERSION ! 6724: # ! 6725: ocom1: cmpl r6,$b$icl # jump if integer ! 6726: beqlu ocom2 ! 6727: cmpl r6,$b$rcl # jump if real ! 6728: beqlu ocom3 ! 6729: jsb gtnum # else convert to numeric ! 6730: .long er_010 # complementation operand is not numeric ! 6731: jmp ocom1 # back to check cases ! 6732: # ! 6733: # HERE TO COMPLEMENT INTEGER ! 6734: # ! 6735: ocom2: movl 4*icval(r9),r5 # load integer value ! 6736: mnegl r5,r5 # negate ! 6737: bvs 0f ! 6738: jmp exint ! 6739: 0: ! 6740: jmp er_011 # complementation caused integer overflow ! 6741: # ! 6742: # HERE TO COMPLEMENT REAL ! 6743: # ! 6744: ocom3: movf 4*rcval(r9),r2 # load real value ! 6745: mnegf r2,r2 # negate ! 6746: jmp exrea # return real result ! 6747: #page ! 6748: # ! 6749: # BINARY SLASH (DIVISION) ! 6750: # ! 6751: o$dvd: # entry point ! 6752: jsb arith # fetch arithmetic operands ! 6753: .long er_012 # division left operand is not numeric ! 6754: .long er_013 # division right operand is not numeric ! 6755: .long odvd2 # jump if real operands ! 6756: # ! 6757: # HERE TO DIVIDE TWO INTEGERS ! 6758: # ! 6759: divl2 4*icval(r10),r5 # divide left operand by right ! 6760: bvs 0f ! 6761: jmp exint ! 6762: 0: ! 6763: jmp er_014 # division caused integer overflow ! 6764: # ! 6765: # HERE TO DIVIDE TWO REALS ! 6766: # ! 6767: odvd2: divf2 4*rcval(r10),r2 # divide left operand by right ! 6768: bvs 0f ! 6769: jmp exrea ! 6770: 0: ! 6771: jmp er_262 # division caused real overflow ! 6772: #page ! 6773: # ! 6774: # EXPONENTIATION ! 6775: # ! 6776: o$exp: # entry point ! 6777: movl (sp)+,r9 # load exponent ! 6778: jsb gtnum # convert to number ! 6779: .long er_015 # exponentiation right operand is not numeric ! 6780: cmpl r6,$b$icl # jump if real ! 6781: beqlu 0f ! 6782: jmp oexp7 ! 6783: 0: ! 6784: movl r9,r10 # move exponent ! 6785: movl (sp)+,r9 # load base ! 6786: jsb gtnum # convert to numeric ! 6787: .long er_016 # exponentiation left operand is not numeric ! 6788: movl 4*icval(r10),r5 # load exponent ! 6789: tstl r5 # error if negative exponent ! 6790: bgeq 0f ! 6791: jmp oexp8 ! 6792: 0: ! 6793: cmpl r6,$b$rcl # jump if base is real ! 6794: beqlu oexp3 ! 6795: # ! 6796: # HERE TO EXPONENTIATE AN INTEGER ! 6797: # ! 6798: movl r5,r6 # convert exponent to 1 word integer ! 6799: bgeq 0f ! 6800: jmp oexp2 ! 6801: 0: ! 6802: # set loop counter ! 6803: movl intv1,r5 # load initial value of 1 ! 6804: tstl r6 # jump if non-zero exponent ! 6805: bnequ oexp1 ! 6806: tstl r5 # give zero as result for nonzero**0 ! 6807: beql 0f ! 6808: jmp exint ! 6809: 0: ! 6810: jmp oexp4 # else error of 0**0 ! 6811: # ! 6812: # LOOP TO PERFORM EXPONENTIATION ! 6813: # ! 6814: oexp1: mull2 4*icval(r9),r5 # multiply by base ! 6815: bvs oexp2 ! 6816: sobgtr r6,oexp1 # loop back till computation complete ! 6817: jmp exint # then return integer result ! 6818: # ! 6819: # HERE IF INTEGER OVERFLOW ! 6820: # ! 6821: oexp2: jmp er_017 # exponentiation caused integer overflow ! 6822: #page ! 6823: # ! 6824: # EXPONENTIATION (CONTINUED) ! 6825: # ! 6826: # HERE TO EXPONENTIATE A REAL ! 6827: # ! 6828: oexp3: movl r5,r6 # convert exponent to one word ! 6829: bgeq 0f ! 6830: jmp oexp6 ! 6831: 0: ! 6832: # set loop counter ! 6833: movf reav1,r2 # load 1.0 as initial value ! 6834: tstl r6 # jump if non-zero exponent ! 6835: bnequ oexp5 ! 6836: tstf r2 # return 1.0 if nonzero**zero ! 6837: beql 0f ! 6838: jmp exrea ! 6839: 0: ! 6840: # ! 6841: # HERE FOR ERROR OF 0**0 OR 0.0**0 ! 6842: # ! 6843: oexp4: jmp er_018 # exponentiation result is undefined ! 6844: # ! 6845: # LOOP TO PERFORM EXPONENTIATION ! 6846: # ! 6847: oexp5: mulf2 4*rcval(r9),r2 # multiply by base ! 6848: bvs oexp6 ! 6849: sobgtr r6,oexp5 # loop till computation complete ! 6850: jmp exrea # then return real result ! 6851: # ! 6852: # HERE IF REAL OVERFLOW ! 6853: # ! 6854: oexp6: jmp er_266 # exponentiation caused real overflow ! 6855: # ! 6856: # HERE IF REAL EXPONENT ! 6857: # ! 6858: oexp7: jmp er_267 # exponentiation right operand is real not integer ! 6859: # ! 6860: # HERE FOR NEGATIVE EXPONENT ! 6861: # ! 6862: oexp8: jmp er_019 # exponentiation right operand is negative ! 6863: #page ! 6864: # ! 6865: # FAILURE IN EXPRESSION EVALUATION ! 6866: # ! 6867: # THIS ENTRY POINT IS USED IF THE EVALUATION OF AN ! 6868: # EXPRESSION, INITIATED BY THE EVALX PROCEDURE, FAILS. ! 6869: # CONTROL IS RETURNED TO AN APPROPRIATE POINT IN EVALX. ! 6870: # ! 6871: o$fex: # entry point ! 6872: jmp evlx6 # jump to failure loc in evalx ! 6873: #page ! 6874: # ! 6875: # FAILURE DURING EVALUATION OF A COMPLEX OR DIRECT GOTO ! 6876: # ! 6877: o$fif: # entry point ! 6878: jmp er_020 # goto evaluation failure ! 6879: #page ! 6880: # ! 6881: # FUNCTION CALL (MORE THAN ONE ARGUMENT) ! 6882: # ! 6883: o$fnc: # entry point ! 6884: movl (r3)+,r6 # load number of arguments ! 6885: movl (r3)+,r9 # load function vrblk pointer ! 6886: movl 4*vrfnc(r9),r10 # load function pointer ! 6887: cmpl r6,4*fargs(r10) # use central routine if wrong num ! 6888: beqlu 0f ! 6889: jmp cfunc ! 6890: 0: ! 6891: movl (r10),r11 # jump to function if arg count ok ! 6892: jmp (r11) ! 6893: #page ! 6894: # ! 6895: # FUNCTION NAME ERROR ! 6896: # ! 6897: o$fne: # entry point ! 6898: movl (r3)+,r6 # get next code word ! 6899: cmpl r6,$ornm$ # fail if not evaluating expression ! 6900: bnequ ofne1 ! 6901: tstl 4*2(sp) # ok if expr. was wanted by value ! 6902: bnequ 0f ! 6903: jmp evlx3 ! 6904: 0: ! 6905: # ! 6906: # HERE FOR ERROR ! 6907: # ! 6908: ofne1: jmp er_021 # function called by name returned a value ! 6909: #page ! 6910: # ! 6911: # FUNCTION CALL (SINGLE ARGUMENT) ! 6912: # ! 6913: o$fns: # entry point ! 6914: movl (r3)+,r9 # load function vrblk pointer ! 6915: movl $num01,r6 # set number of arguments to one ! 6916: movl 4*vrfnc(r9),r10 # load function pointer ! 6917: cmpl r6,4*fargs(r10) # use central routine if wrong num ! 6918: beqlu 0f ! 6919: jmp cfunc ! 6920: 0: ! 6921: movl (r10),r11 # jump to function if arg count ok ! 6922: jmp (r11) ! 6923: #page ! 6924: # CALL TO UNDEFINED FUNCTION ! 6925: # ! 6926: o$fun: # entry point ! 6927: jmp er_022 # undefined function called ! 6928: #page ! 6929: # ! 6930: # EXECUTE COMPLEX GOTO ! 6931: # ! 6932: o$goc: # entry point ! 6933: movl 4*1(sp),r9 # load name base pointer ! 6934: cmpl r9,state # jump if not natural variable ! 6935: bgequ ogoc1 ! 6936: addl2 $4*vrtra,r9 # else point to vrtra field ! 6937: movl (r9),r11 # and jump through it ! 6938: jmp (r11) ! 6939: # ! 6940: # HERE IF GOTO OPERAND IS NOT NATURAL VARIABLE ! 6941: # ! 6942: ogoc1: jmp er_023 # goto operand is not a natural variable ! 6943: #page ! 6944: # ! 6945: # EXECUTE DIRECT GOTO ! 6946: # ! 6947: o$god: # entry point ! 6948: movl (sp),r9 # load operand ! 6949: movl (r9),r6 # load first word ! 6950: cmpl r6,$b$cds # jump if code block to code routine ! 6951: bnequ 0f ! 6952: jmp bcds0 ! 6953: 0: ! 6954: cmpl r6,$b$cdc # jump if code block to code routine ! 6955: bnequ 0f ! 6956: jmp bcdc0 ! 6957: 0: ! 6958: jmp er_024 # goto operand in direct goto is not code ! 6959: #page ! 6960: # ! 6961: # SET GOTO FAILURE TRAP ! 6962: # ! 6963: # THIS ROUTINE IS EXECUTED AT THE START OF A COMPLEX OR ! 6964: # DIRECT FAILURE GOTO TO TRAP A SUBSEQUENT FAIL (SEE EXFAL) ! 6965: # ! 6966: o$gof: # entry point ! 6967: movl flptr,r9 # point to fail offset on stack ! 6968: addl2 $4,(r9) # point failure to o$fif word ! 6969: tstl (r3)+ # point to next code word ! 6970: jmp exits # exit to continue ! 6971: #page ! 6972: # ! 6973: # BINARY DOLLAR (IMMEDIATE ASSIGNMENT) ! 6974: # ! 6975: # THE PATTERN BUILT BY BINARY DOLLAR IS A COMPOUND PATTERN. ! 6976: # SEE DESCRIPTION AT START OF PATTERN MATCH SECTION FOR ! 6977: # DETAILS OF THE STRUCTURE WHICH IS CONSTRUCTED. ! 6978: # ! 6979: o$ima: # entry point ! 6980: movl $p$imc,r7 # set pcode for last node ! 6981: movl (sp)+,r8 # pop name offset (parm2) ! 6982: movl (sp)+,r9 # pop name base (parm1) ! 6983: jsb pbild # build p$imc node ! 6984: movl r9,r10 # save ptr to node ! 6985: movl (sp),r9 # load left argument ! 6986: jsb gtpat # convert to pattern ! 6987: .long er_025 # immediate assignment left operand is not pattern ! 6988: movl r9,(sp) # save ptr to left operand pattern ! 6989: movl $p$ima,r7 # set pcode for first node ! 6990: jsb pbild # build p$ima node ! 6991: movl (sp)+,4*pthen(r9)# set left operand as p$ima successor ! 6992: jsb pconc # concatenate to form final pattern ! 6993: jmp exixr # all done ! 6994: #page ! 6995: # ! 6996: # INDIRECTION (BY NAME) ! 6997: # ! 6998: o$inn: # entry point ! 6999: movl sp,r7 # set flag for result by name ! 7000: jmp indir # jump to common routine ! 7001: #page ! 7002: # ! 7003: # INTERROGATION ! 7004: # ! 7005: o$int: # entry point ! 7006: movl $nulls,(sp) # replace operand with null ! 7007: jmp exits # exit for next code word ! 7008: #page ! 7009: # ! 7010: # INDIRECTION (BY VALUE) ! 7011: # ! 7012: o$inv: # entry point ! 7013: clrl r7 # set flag for by value ! 7014: jmp indir # jump to common routine ! 7015: #page ! 7016: # ! 7017: # KEYWORD REFERENCE (BY NAME) ! 7018: # ! 7019: o$kwn: # entry point ! 7020: jsb kwnam # get keyword name ! 7021: jmp exnam # exit with result name ! 7022: #page ! 7023: # ! 7024: # KEYWORD REFERENCE (BY VALUE) ! 7025: # ! 7026: o$kwv: # entry point ! 7027: jsb kwnam # get keyword name ! 7028: movl r9,dnamp # delete kvblk ! 7029: jsb acess # access value ! 7030: .long exnul # dummy (unused) failure return ! 7031: jmp exixr # jump with value in xr ! 7032: #page ! 7033: # ! 7034: # LOAD EXPRESSION BY NAME ! 7035: # ! 7036: o$lex: # entry point ! 7037: movl $4*evsi$,r6 # set size of evblk ! 7038: jsb alloc # allocate space for evblk ! 7039: movl $b$evt,(r9) # set type word ! 7040: movl $trbev,4*evvar(r9) # set dummy trblk pointer ! 7041: movl (r3)+,r6 # load exblk pointer ! 7042: movl r6,4*evexp(r9) # set exblk pointer ! 7043: movl r9,r10 # move name base to proper reg ! 7044: movl $4*evvar,r6 # set name offset = zero ! 7045: jmp exnam # exit with name in (xl,wa) ! 7046: #page ! 7047: # ! 7048: # LOAD PATTERN VALUE ! 7049: # ! 7050: o$lpt: # entry point ! 7051: movl (r3)+,r9 # load pattern pointer ! 7052: jmp exixr # stack ptr and obey next code word ! 7053: #page ! 7054: # ! 7055: # LOAD VARIABLE NAME ! 7056: # ! 7057: o$lvn: # entry point ! 7058: movl (r3)+,r6 # load vrblk pointer ! 7059: movl r6,-(sp) # stack vrblk ptr (name base) ! 7060: movl $4*vrval,-(sp) # stack name offset ! 7061: jmp exits # exit with result on stack ! 7062: #page ! 7063: # ! 7064: # BINARY ASTERISK (MULTIPLICATION) ! 7065: # ! 7066: o$mlt: # entry point ! 7067: jsb arith # fetch arithmetic operands ! 7068: .long er_026 # multiplication left operand is not numeric ! 7069: .long er_027 # multiplication right operand is not numeric ! 7070: .long omlt1 # jump if real operands ! 7071: # ! 7072: # HERE TO MULTIPLY TWO INTEGERS ! 7073: # ! 7074: mull2 4*icval(r10),r5 # multiply left operand by right ! 7075: bvs 0f ! 7076: jmp exint ! 7077: 0: ! 7078: jmp er_028 # multiplication caused integer overflow ! 7079: # ! 7080: # HERE TO MULTIPLY TWO REALS ! 7081: # ! 7082: omlt1: mulf2 4*rcval(r10),r2 # multiply left operand by right ! 7083: bvs 0f ! 7084: jmp exrea ! 7085: 0: ! 7086: jmp er_263 # multiplication caused real overflow ! 7087: #page ! 7088: # ! 7089: # NAME REFERENCE ! 7090: # ! 7091: o$nam: # entry point ! 7092: movl $4*nmsi$,r6 # set length of nmblk ! 7093: jsb alloc # allocate nmblk ! 7094: movl $b$nml,(r9) # set name block code ! 7095: movl (sp)+,4*nmofs(r9)# set name offset from operand ! 7096: movl (sp)+,4*nmbas(r9)# set name base from operand ! 7097: jmp exixr # exit with result in xr ! 7098: #page ! 7099: # ! 7100: # NEGATION ! 7101: # ! 7102: # INITIAL ENTRY ! 7103: # ! 7104: o$nta: # entry point ! 7105: movl (r3)+,r6 # load new failure offset ! 7106: movl flptr,-(sp) # stack old failure pointer ! 7107: movl r6,-(sp) # stack new failure offset ! 7108: movl sp,flptr # set new failure pointer ! 7109: jmp exits # jump to continue execution ! 7110: # ! 7111: # ENTRY AFTER SUCCESSFUL EVALUATION OF OPERAND ! 7112: # ! 7113: o$ntb: # entry point ! 7114: movl 4*2(sp),flptr # restore old failure pointer ! 7115: jmp exfal # and fail ! 7116: # ! 7117: # ENTRY FOR FAILURE DURING OPERAND EVALUATION ! 7118: # ! 7119: o$ntc: # entry point ! 7120: addl2 $4,sp # pop failure offset ! 7121: movl (sp)+,flptr # restore old failure pointer ! 7122: jmp exnul # exit giving null result ! 7123: #page ! 7124: # ! 7125: # USE OF UNDEFINED OPERATOR ! 7126: # ! 7127: o$oun: # entry point ! 7128: jmp er_029 # undefined operator referenced ! 7129: #page ! 7130: # ! 7131: # BINARY DOT (PATTERN ASSIGNMENT) ! 7132: # ! 7133: # THE PATTERN BUILT BY BINARY DOT IS A COMPOUND PATTERN. ! 7134: # SEE DESCRIPTION AT START OF PATTERN MATCH SECTION FOR ! 7135: # DETAILS OF THE STRUCTURE WHICH IS CONSTRUCTED. ! 7136: # ! 7137: o$pas: # entry point ! 7138: movl $p$pac,r7 # load pcode for p$pac node ! 7139: movl (sp)+,r8 # load name offset (parm2) ! 7140: movl (sp)+,r9 # load name base (parm1) ! 7141: jsb pbild # build p$pac node ! 7142: movl r9,r10 # save ptr to node ! 7143: movl (sp),r9 # load left operand ! 7144: jsb gtpat # convert to pattern ! 7145: .long er_030 # pattern assignment left operand is not pattern ! 7146: movl r9,(sp) # save ptr to left operand pattern ! 7147: movl $p$paa,r7 # set pcode for p$paa node ! 7148: jsb pbild # build p$paa node ! 7149: movl (sp)+,4*pthen(r9)# set left operand as p$paa successor ! 7150: jsb pconc # concatenate to form final pattern ! 7151: jmp exixr # jump for next code word ! 7152: #page ! 7153: # ! 7154: # PATTERN MATCH (BY NAME, FOR REPLACEMENT) ! 7155: # ! 7156: o$pmn: # entry point ! 7157: clrl r7 # set type code for match by name ! 7158: jmp match # jump to routine to start match ! 7159: #page ! 7160: # ! 7161: # PATTERN MATCH (STATEMENT) ! 7162: # ! 7163: # O$PMS IS USED IN PLACE OF O$PMV WHEN THE PATTERN MATCH ! 7164: # OCCURS AT THE OUTER (STATEMENT) LEVEL SINCE IN THIS ! 7165: # CASE THE SUBSTRING VALUE NEED NOT BE CONSTRUCTED. ! 7166: # ! 7167: o$pms: # entry point ! 7168: movl $num02,r7 # set flag for statement to match ! 7169: jmp match # jump to routine to start match ! 7170: #page ! 7171: # ! 7172: # PATTERN MATCH (BY VALUE) ! 7173: # ! 7174: o$pmv: # entry point ! 7175: movl $num01,r7 # set type code for value match ! 7176: jmp match # jump to routine to start match ! 7177: #page ! 7178: # ! 7179: # POP TOP ITEM ON STACK ! 7180: # ! 7181: o$pop: # entry point ! 7182: addl2 $4,sp # pop top stack entry ! 7183: jmp exits # obey next code word ! 7184: #page ! 7185: # ! 7186: # TERMINATE EXECUTION (CODE COMPILED FOR END STATEMENT) ! 7187: # ! 7188: o$stp: # entry point ! 7189: jmp lend0 # jump to end circuit ! 7190: #page ! 7191: # ! 7192: # RETURN NAME FROM EXPRESSION ! 7193: # THIS ENTRY POINTS IS USED IF THE EVALUATION OF AN ! 7194: # EXPRESSION, INITIATED BY THE EVALX PROCEDURE, RETURNS ! 7195: # A NAME. CONTROL IS RETURNED TO THE PROPER POINT IN EVALX. ! 7196: # ! 7197: o$rnm: # entry point ! 7198: jmp evlx4 # return to evalx procedure ! 7199: #page ! 7200: # ! 7201: # PATTERN REPLACEMENT ! 7202: # ! 7203: # WHEN THIS ROUTINE GETS CONTROL, THE FOLLOWING STACK ! 7204: # ENTRIES HAVE BEEN MADE (SEE END OF MATCH ROUTINE P$NTH) ! 7205: # ! 7206: # SUBJECT NAME BASE ! 7207: # SUBJECT NAME OFFSET ! 7208: # INITIAL CURSOR VALUE ! 7209: # FINAL CURSOR VALUE ! 7210: # SUBJECT POINTER ! 7211: # (XS) ---------------- REPLACEMENT VALUE ! 7212: # ! 7213: o$rpl: # entry point ! 7214: jsb gtstg # convert replacement val to string ! 7215: .long er_031 # pattern replacement right operand is not string ! 7216: # ! 7217: # GET RESULT LENGTH AND ALLOCATE RESULT SCBLK ! 7218: # ! 7219: movl (sp),r10 # load subject string pointer ! 7220: cmpl (r10),$b$bct # branch if buffer assignment ! 7221: bnequ 0f ! 7222: jmp orpl4 ! 7223: 0: ! 7224: addl2 4*sclen(r10),r6 # add subject string length ! 7225: addl2 4*2(sp),r6 # add starting cursor ! 7226: subl2 4*1(sp),r6 # minus final cursor = total length ! 7227: tstl r6 # jump if result is null ! 7228: bnequ 0f ! 7229: jmp orpl3 ! 7230: 0: ! 7231: movl r9,-(sp) # restack replacement string ! 7232: jsb alocs # allocate scblk for result ! 7233: movl 4*3(sp),r6 # get initial cursor (part 1 len) ! 7234: movl r9,4*3(sp) # stack result pointer ! 7235: movab cfp$f(r9),r9 # point to characters of result ! 7236: # ! 7237: # MOVE PART 1 (START OF SUBJECT) TO RESULT ! 7238: # ! 7239: tstl r6 # jump if first part is null ! 7240: beqlu orpl1 ! 7241: movl 4*1(sp),r10 # else point to subject string ! 7242: movab cfp$f(r10),r10 # point to subject string chars ! 7243: jsb sbmvc # move first part to result ! 7244: #page ! 7245: # PATTERN REPLACEMENT (CONTINUED) ! 7246: # ! 7247: # NOW MOVE IN REPLACEMENT VALUE ! 7248: # ! 7249: orpl1: movl (sp)+,r10 # load replacement string, pop ! 7250: movl 4*sclen(r10),r6 # load length ! 7251: tstl r6 # jump if null replacement ! 7252: beqlu orpl2 ! 7253: movab cfp$f(r10),r10 # else point to chars of replacement ! 7254: jsb sbmvc # move in chars (part 2) ! 7255: # ! 7256: # NOW MOVE IN REMAINDER OF STRING (PART 3) ! 7257: # ! 7258: orpl2: movl (sp)+,r10 # load subject string pointer, pop ! 7259: movl (sp)+,r8 # load final cursor, pop ! 7260: movl 4*sclen(r10),r6 # load subject string length ! 7261: subl2 r8,r6 # minus final cursor = part 3 length ! 7262: tstl r6 # jump to assign if part 3 is null ! 7263: bnequ 0f ! 7264: jmp oass0 ! 7265: 0: ! 7266: movab cfp$f(r10)[r8],r10 # else point to last part of string ! 7267: jsb sbmvc # move part 3 to result ! 7268: jmp oass0 # jump to perform assignment ! 7269: # ! 7270: # HERE IF RESULT IS NULL ! 7271: # ! 7272: orpl3: addl2 $4*num02,sp # pop subject str ptr, final cursor ! 7273: movl $nulls,(sp) # set null result ! 7274: jmp oass0 # jump to assign null value ! 7275: # ! 7276: # HERE FOR BUFFER SUBSTRING ASSIGNMENT ! 7277: # ! 7278: orpl4: movl r9,r10 # copy scblk replacement ptr ! 7279: movl (sp)+,r9 # unstack bcblk ptr ! 7280: movl (sp)+,r7 # get final cursor value ! 7281: movl (sp)+,r6 # get initial cursor ! 7282: subl2 r6,r7 # get length in wb ! 7283: addl2 $4*num02,sp # get rid of name base/offset ! 7284: jsb insbf # insert substring ! 7285: .long invalid$ # convert fail impossible ! 7286: .long exfal # fail if insert fails ! 7287: jmp exnul # else null result ! 7288: #page ! 7289: # ! 7290: # RETURN VALUE FROM EXPRESSION ! 7291: # ! 7292: # THIS ENTRY POINTS IS USED IF THE EVALUATION OF AN ! 7293: # EXPRESSION, INITIATED BY THE EVALX PROCEDURE, RETURNS ! 7294: # A VALUE. CONTROL IS RETURNED TO THE PROPER POINT IN EVALX ! 7295: # ! 7296: o$rvl: # entry point ! 7297: jmp evlx3 # return to evalx procedure ! 7298: #page ! 7299: # ! 7300: # SELECTION ! 7301: # ! 7302: # INITIAL ENTRY ! 7303: # ! 7304: o$sla: # entry point ! 7305: movl (r3)+,r6 # load new failure offset ! 7306: movl flptr,-(sp) # stack old failure pointer ! 7307: movl r6,-(sp) # stack new failure offset ! 7308: movl sp,flptr # set new failure pointer ! 7309: jmp exits # jump to execute first alternative ! 7310: # ! 7311: # ENTRY AFTER SUCCESSFUL EVALUATION OF ALTERNATIVE ! 7312: # ! 7313: o$slb: # entry point ! 7314: movl (sp)+,r9 # load result ! 7315: addl2 $4,sp # pop fail offset ! 7316: movl (sp),flptr # restore old failure pointer ! 7317: movl r9,(sp) # restack result ! 7318: movl (r3)+,r6 # load new code offset ! 7319: addl2 r$cod,r6 # point to absolute code location ! 7320: movl r6,r3 # set new code pointer ! 7321: jmp exits # jump to continue past selection ! 7322: # ! 7323: # ENTRY AT START OF SUBSEQUENT ALTERNATIVES ! 7324: # ! 7325: o$slc: # entry point ! 7326: movl (r3)+,r6 # load new fail offset ! 7327: movl r6,(sp) # store new fail offset ! 7328: jmp exits # jump to execute next alternative ! 7329: # ! 7330: # ENTRY AT START OF LAST ALTERNATIVE ! 7331: # ! 7332: o$sld: # entry point ! 7333: addl2 $4,sp # pop failure offset ! 7334: movl (sp)+,flptr # restore old failure pointer ! 7335: jmp exits # jump to execute last alternative ! 7336: #page ! 7337: # ! 7338: # BINARY MINUS (SUBTRACTION) ! 7339: # ! 7340: o$sub: # entry point ! 7341: jsb arith # fetch arithmetic operands ! 7342: .long er_032 # subtraction left operand is not numeric ! 7343: .long er_033 # subtraction right operand is not numeric ! 7344: .long osub1 # jump if real operands ! 7345: # ! 7346: # HERE TO SUBTRACT TWO INTEGERS ! 7347: # ! 7348: subl2 4*icval(r10),r5 # subtract right operand from left ! 7349: bvs 0f ! 7350: jmp exint ! 7351: 0: ! 7352: jmp er_034 # subtraction caused integer overflow ! 7353: # ! 7354: # HERE TO SUBTRACT TWO REALS ! 7355: # ! 7356: osub1: subf2 4*rcval(r10),r2 # subtract right operand from left ! 7357: bvs 0f ! 7358: jmp exrea ! 7359: 0: ! 7360: jmp er_264 # subtraction caused real overflow ! 7361: #page ! 7362: # ! 7363: # DUMMY OPERATOR TO RETURN CONTROL TO TRXEQ PROCEDURE ! 7364: # ! 7365: o$txr: # entry point ! 7366: jmp trxq1 # jump into trxeq procedure ! 7367: #page ! 7368: # ! 7369: # UNEXPECTED FAILURE ! 7370: # ! 7371: # NOTE THAT IF A SETEXIT TRAP IS OPERATING THEN ! 7372: # TRANSFER TO SYSTEM LABEL CONTINUE ! 7373: # WILL RESULT IN LOOPING HERE. DIFFICULT TO AVOID EXCEPT ! 7374: # WITH A CONSIDERABLE OVERHEAD WHICH IS NOT WORTHWHILE OR ! 7375: # ELSE BY A TECHNIQUE SUCH AS SETTING KVERL TO ZERO. ! 7376: # ! 7377: o$unf: # entry point ! 7378: jmp er_035 # unexpected failure in -nofail mode ! 7379: #title s p i t b o l -- snobol4 builtin label routines ! 7380: # ! 7381: # THE FOLLOWING SECTION CONTAINS THE ROUTINES FOR LABELS ! 7382: # WHICH HAVE A PREDEFINED MEANING IN SNOBOL4. ! 7383: # ! 7384: # CONTROL IS PASSED DIRECTLY TO THE LABEL NAME ENTRY POINT. ! 7385: # ! 7386: # ENTRY NAMES ARE OF THE FORM L$XXX WHERE XXX IS THE THREE ! 7387: # LETTER VARIABLE NAME IDENTIFIER. ! 7388: # ! 7389: # ENTRIES ARE IN ALPHABETICAL ORDER ! 7390: #page ! 7391: # ! 7392: # ABORT ! 7393: # ! 7394: l$abo: # entry point ! 7395: # ! 7396: # MERGE HERE IF EXECUTION TERMINATES IN ERROR ! 7397: # ! 7398: labo1: movl kvert,r6 # load error code ! 7399: tstl r6 # jump if no error has occured ! 7400: beqlu labo2 ! 7401: jsb sysax # call after execution proc (reg04) ! 7402: jsb prtpg # else eject printer ! 7403: jsb ermsg # print error message ! 7404: clrl r9 # indicate no message to print ! 7405: jmp stopr # jump to routine to stop run ! 7406: # ! 7407: # HERE IF NO ERROR HAD OCCURED ! 7408: # ! 7409: labo2: jmp er_036 # goto abort with no preceding error ! 7410: #page ! 7411: # ! 7412: # CONTINUE ! 7413: # ! 7414: l$cnt: # entry point ! 7415: # ! 7416: # MERGE HERE AFTER EXECUTION ERROR ! 7417: # ! 7418: lcnt1: movl r$cnt,r9 # load continuation code block ptr ! 7419: tstl r9 # jump if no previous error ! 7420: beqlu lcnt2 ! 7421: clrl r$cnt # clear flag ! 7422: movl r9,r$cod # else store as new code block ptr ! 7423: addl2 stxof,r9 # add failure offset ! 7424: movl r9,r3 # load code pointer ! 7425: movl flptr,sp # reset stack pointer ! 7426: jmp exits # jump to take indicated failure ! 7427: # ! 7428: # HERE IF NO PREVIOUS ERROR ! 7429: # ! 7430: lcnt2: jmp er_037 # goto continue with no preceding error ! 7431: #page ! 7432: # ! 7433: # END ! 7434: # ! 7435: l$end: # entry point ! 7436: # ! 7437: # MERGE HERE FROM END CODE CIRCUIT ! 7438: # ! 7439: lend0: movl $endms,r9 # point to message /normal term../ ! 7440: jmp stopr # jump to routine to stop run ! 7441: #page ! 7442: # ! 7443: # FRETURN ! 7444: # ! 7445: l$frt: # entry point ! 7446: movl $scfrt,r6 # point to string /freturn/ ! 7447: jmp retrn # jump to common return routine ! 7448: #page ! 7449: # ! 7450: # NRETURN ! 7451: # ! 7452: l$nrt: # entry point ! 7453: movl $scnrt,r6 # point to string /nreturn/ ! 7454: jmp retrn # jump to common return routine ! 7455: #page ! 7456: # ! 7457: # RETURN ! 7458: # ! 7459: l$rtn: # entry point ! 7460: movl $scrtn,r6 # point to string /return/ ! 7461: jmp retrn # jump to common return routine ! 7462: #page ! 7463: # ! 7464: # UNDEFINED LABEL ! 7465: # ! 7466: l$und: # entry point ! 7467: jmp er_038 # goto undefined label ! 7468: #title s p i t b o l -- block action routines ! 7469: # ! 7470: # THE FIRST WORD OF EVERY BLOCK IN DYNAMIC STORAGE AND THE ! 7471: # VRGET, VRSTO AND VRTRA FIELDS OF A VRBLK CONTAIN A ! 7472: # POINTER TO AN ENTRY POINT IN THE PROGRAM. ALL SUCH ENTRY ! 7473: # POINTS ARE IN THE FOLLOWING SECTION EXCEPT THOSE FOR ! 7474: # PATTERN BLOCKS WHICH ARE IN THE PATTERN MATCHING SEGMENT ! 7475: # LATER ON (LABELS OF THE FORM P$XXX), AND DOPE VECTORS ! 7476: # (D$XXX) WHICH ARE IN THE DOPE VECTOR SECTION FOLLOWING ! 7477: # THE PATTERN ROUTINES (DOPE VECTORS ARE USED FOR CMBLKS). ! 7478: # ! 7479: # THE ENTRY POINTS IN THIS SECTION HAVE LABELS OF THE ! 7480: # FORM B$XXY WHERE XX IS THE TWO CHARACTER BLOCK TYPE FOR ! 7481: # THE CORRESPONDING BLOCK AND Y IS ANY LETTER. ! 7482: # ! 7483: # IN SOME CASES, THE POINTERS SERVE NO OTHER PURPOSE THAN ! 7484: # TO IDENTIFY THE BLOCK TYPE. IN THIS CASE THE ROUTINE ! 7485: # IS NEVER EXECUTED AND THUS NO CODE IS ASSEMBLED. ! 7486: # ! 7487: # FOR EACH OF THESE ENTRY POINTS CORRESPONDING TO A BLOCK ! 7488: # AN ENTRY POINT IDENTIFICATION IS ASSEMBLED (BL$XX). ! 7489: # ! 7490: # THE EXACT ENTRY CONDITIONS DEPEND ON THE MANNER IN ! 7491: # WHICH THE ROUTINE IS ACCESSED AND ARE DOCUMENTED WITH ! 7492: # THE INDIVIDUAL ROUTINES AS REQUIRED. ! 7493: # ! 7494: # THE ORDER OF THESE ROUTINES IS ALPHABETICAL WITH THE ! 7495: # FOLLOWING EXCEPTIONS. ! 7496: # ! 7497: # THE ROUTINES FOR SEBLK AND EXBLK ENTRIES OCCUR FIRST SO ! 7498: # THAT EXPRESSIONS CAN BE QUICKLY IDENTIFIED FROM THE FACT ! 7499: # THAT THEIR ROUTINES LIE BEFORE THE SYMBOL B$E$$. ! 7500: # ! 7501: # THESE ARE IMMEDIATELY FOLLOWED BY THE ROUTINE FOR A TRBLK ! 7502: # SO THAT THE TEST AGAINST THE SYMBOL B$T$$ CHECKS FOR ! 7503: # TRAPPED VALUES OR EXPRESSION VALUES (SEE PROCEDURE EVALP) ! 7504: # ! 7505: # THE PATTERN ROUTINES LIE AFTER THIS SECTION SO THAT ! 7506: # PATTERNS ARE IDENTIFIED WITH ROUTINES STARTING AT OR ! 7507: # AFTER THE INITIAL INSTRUCTION IN THESE ROUTINES (P$AAA). ! 7508: # ! 7509: # THE SYMBOL B$AAA DEFINES THE FIRST LOCATION FOR BLOCK ! 7510: # ROUTINES AND THE SYMBOL P$YYY (AT THE END OF THE PATTERN ! 7511: # MATCH ROUTINES SECTION) DEFINES THE LAST SUCH ENTRY POINT ! 7512: # ! 7513: .align 2 ! 7514: .word bl$$i ! 7515: b$aaa: # entry point of first block routine ! 7516: #page ! 7517: # ! 7518: # EXBLK ! 7519: # ! 7520: # THE ROUTINE FOR AN EXBLK LOADS THE EXPRESSION ONTO ! 7521: # THE STACK AS A VALUE. ! 7522: # ! 7523: # (XR) POINTER TO EXBLK ! 7524: # ! 7525: .align 2 ! 7526: .word bl$ex ! 7527: b$exl: # entry point (exblk) ! 7528: jmp exixr # stack xr and obey next code word ! 7529: #page ! 7530: # ! 7531: # SEBLK ! 7532: # ! 7533: # THE ROUTINE FOR SEBLK IS ACCESSED FROM THE GENERATED ! 7534: # CODE TO LOAD THE EXPRESSION VALUE ONTO THE STACK. ! 7535: # ! 7536: .align 2 ! 7537: .word bl$se ! 7538: b$sel: # entry point (seblk) ! 7539: jmp exixr # stack xr and obey next code word ! 7540: # ! 7541: # DEFINE SYMBOL WHICH MARKS END OF ENTRIES FOR EXPRESSIONS ! 7542: # ! 7543: .align 2 ! 7544: .word bl$$i ! 7545: b$e$$: # entry point ! 7546: #page ! 7547: # ! 7548: # TRBLK ! 7549: # ! 7550: # THE ROUTINE FOR A TRBLK IS NEVER EXECUTED ! 7551: # ! 7552: .align 2 ! 7553: .word bl$tr ! 7554: b$trt: # entry point (trblk) ! 7555: # ! 7556: # DEFINE SYMBOL MARKING END OF TRAP AND EXPRESSION BLOCKS ! 7557: # ! 7558: .align 2 ! 7559: .word bl$$i ! 7560: b$t$$: # end of trblk,seblk,exblk entries ! 7561: #page ! 7562: # ! 7563: # ARBLK ! 7564: # ! 7565: # THE ROUTINE FOR ARBLK IS NEVER EXECUTED ! 7566: # ! 7567: .align 2 ! 7568: .word bl$ar ! 7569: b$art: # entry point (arblk) ! 7570: #page ! 7571: # ! 7572: # BCBLK ! 7573: # ! 7574: # THE ROUTINE FOR A BCBLK IS NEVER EXECUTED ! 7575: # ! 7576: # (XR) POINTER TO BCBLK ! 7577: # ! 7578: .align 2 ! 7579: .word bl$bc ! 7580: b$bct: # entry point (bcblk) ! 7581: #page ! 7582: # ! 7583: # BFBLK ! 7584: # ! 7585: # THE ROUTINE FOR A BFBLK IS NEVER EXECUTED ! 7586: # ! 7587: # (XR) POINTER TO BFBLK ! 7588: # ! 7589: .align 2 ! 7590: .word bl$bf ! 7591: b$bft: # entry point (bfblk) ! 7592: #page ! 7593: # ! 7594: # CCBLK ! 7595: # ! 7596: # THE ROUTINE FOR CCBLK IS NEVER ENTERED ! 7597: # ! 7598: .align 2 ! 7599: .word bl$cc ! 7600: b$cct: # entry point (ccblk) ! 7601: #page ! 7602: # ! 7603: # CDBLK ! 7604: # ! 7605: # THE CDBLK ROUTINES ARE EXECUTED FROM THE GENERATED CODE. ! 7606: # THERE ARE TWO CASES DEPENDING ON THE FORM OF CDFAL. ! 7607: # ! 7608: # ENTRY FOR COMPLEX FAILURE CODE AT CDFAL ! 7609: # ! 7610: # (XR) POINTER TO CDBLK ! 7611: # ! 7612: .align 2 ! 7613: .word bl$cd ! 7614: b$cdc: # entry point (cdblk) ! 7615: bcdc0: movl flptr,sp # pop garbage off stack ! 7616: movl 4*cdfal(r9),(sp)# set failure offset ! 7617: jmp stmgo # enter stmt ! 7618: #page ! 7619: # ! 7620: # CDBLK (CONTINUED) ! 7621: # ! 7622: # ENTRY FOR SIMPLE FAILURE CODE AT CDFAL ! 7623: # ! 7624: # (XR) POINTER TO CDBLK ! 7625: # ! 7626: .align 2 ! 7627: .word bl$cd ! 7628: b$cds: # entry point (cdblk) ! 7629: bcds0: movl flptr,sp # pop garbage off stack ! 7630: movl $4*cdfal,(sp) # set failure offset ! 7631: jmp stmgo # enter stmt ! 7632: #page ! 7633: # ! 7634: # CMBLK ! 7635: # ! 7636: # THE ROUTINE FOR A CMBLK IS NEVER EXECUTED ! 7637: # ! 7638: .align 2 ! 7639: .word bl$cm ! 7640: b$cmt: # entry point (cmblk) ! 7641: #page ! 7642: # ! 7643: # CTBLK ! 7644: # ! 7645: # THE ROUTINE FOR A CTBLK IS NEVER EXECUTED ! 7646: # ! 7647: .align 2 ! 7648: .word bl$ct ! 7649: b$ctt: # entry point (ctblk) ! 7650: #page ! 7651: # ! 7652: # DFBLK ! 7653: # ! 7654: # THE ROUTINE FOR A DFBLK IS ACCESSED FROM THE O$FNC ENTRY ! 7655: # TO CALL A DATATYPE FUNCTION AND BUILD A PDBLK. ! 7656: # ! 7657: # (XL) POINTER TO DFBLK ! 7658: # ! 7659: .align 2 ! 7660: .word bl$df ! 7661: b$dfc: # entry point ! 7662: movl 4*dfpdl(r10),r6 # load length of pdblk ! 7663: jsb alloc # allocate pdblk ! 7664: movl $b$pdt,(r9) # store type word ! 7665: movl r10,4*pddfp(r9) # store dfblk pointer ! 7666: movl r9,r8 # save pointer to pdblk ! 7667: addl2 r6,r9 # point past pdblk ! 7668: movl 4*fargs(r10),r6 # set to count fields ! 7669: # ! 7670: # LOOP TO ACQUIRE FIELD VALUES FROM STACK ! 7671: # ! 7672: bdfc1: movl (sp)+,-(r9) # move a field value ! 7673: sobgtr r6,bdfc1 # loop till all moved ! 7674: movl r8,r9 # recall pointer to pdblk ! 7675: jmp exsid # exit setting id field ! 7676: #page ! 7677: # ! 7678: # EFBLK ! 7679: # ! 7680: # THE ROUTINE FOR AN EFBLK IS PASSED CONTROL FORM THE O$FNC ! 7681: # ENTRY TO CALL AN EXTERNAL FUNCTION. ! 7682: # ! 7683: # (XL) POINTER TO EFBLK ! 7684: # ! 7685: .align 2 ! 7686: .word bl$ef ! 7687: b$efc: # entry point (efblk) ! 7688: movl 4*fargs(r10),r8 # load number of arguments ! 7689: moval 0[r8],r8 # convert to offset ! 7690: movl r10,-(sp) # save pointer to efblk ! 7691: movl sp,r10 # copy pointer to arguments ! 7692: # ! 7693: # LOOP TO CONVERT ARGUMENTS ! 7694: # ! 7695: befc1: addl2 $4,r10 # point to next entry ! 7696: movl (sp),r9 # load pointer to efblk ! 7697: subl2 $4,r8 # decrement eftar offset ! 7698: addl2 r8,r9 # point to next eftar entry ! 7699: movl 4*eftar(r9),r9 # load eftar entry ! 7700: casel r9,$0,$4 # switch on type ! 7701: 5: ! 7702: .word befc7-5b # no conversion needed ! 7703: .word befc2-5b # string ! 7704: .word befc3-5b # integer ! 7705: .word befc4-5b # real ! 7706: #esw # end of switch on type ! 7707: # ! 7708: # HERE TO CONVERT TO STRING ! 7709: # ! 7710: befc2: movl (r10),-(sp) # stack arg ptr ! 7711: jsb gtstg # convert argument to string ! 7712: .long er_039 # external function argument is not string ! 7713: jmp befc6 # jump to merge ! 7714: #page ! 7715: # ! 7716: # EFBLK (CONTINUED) ! 7717: # ! 7718: # HERE TO CONVERT AN INTEGER ! 7719: # ! 7720: befc3: movl (r10),r9 # load next argument ! 7721: movl r8,befof # save offset ! 7722: jsb gtint # convert to integer ! 7723: .long er_040 # external function argument is not integer ! 7724: jmp befc5 # merge with real case ! 7725: # ! 7726: # HERE TO CONVERT A REAL ! 7727: # ! 7728: befc4: movl (r10),r9 # load next argument ! 7729: movl r8,befof # save offset ! 7730: jsb gtrea # convert to real ! 7731: .long er_265 # external function argument is not real ! 7732: # ! 7733: # INTEGER CASE MERGES HERE ! 7734: # ! 7735: befc5: movl befof,r8 # restore offset ! 7736: # ! 7737: # STRING MERGES HERE ! 7738: # ! 7739: befc6: movl r9,(r10) # store converted result ! 7740: # ! 7741: # NO CONVERSION MERGES HERE ! 7742: # ! 7743: befc7: tstl r8 # loop back if more to go ! 7744: bnequ befc1 ! 7745: # ! 7746: # HERE AFTER CONVERTING ALL THE ARGUMENTS ! 7747: # ! 7748: movl (sp)+,r10 # restore efblk pointer ! 7749: movl 4*fargs(r10),r6 # get number of args ! 7750: jsb sysex # call routine to call external fnc ! 7751: .long exfal # fail if failure ! 7752: #page ! 7753: # ! 7754: # EFBLK (CONTINUED) ! 7755: # ! 7756: # RETURN HERE WITH RESULT IN XR ! 7757: # ! 7758: # FIRST DEFEND AGAINST NON-STANDARD NULL STRING RETURNED ! 7759: # ! 7760: movl 4*efrsl(r10),r7 # get result type id ! 7761: tstl r7 # branch if not unconverted ! 7762: bnequ befa8 ! 7763: cmpl (r9),$b$scl # jump if not a string ! 7764: bnequ befc8 ! 7765: tstl 4*sclen(r9) # return null if null ! 7766: bnequ 0f ! 7767: jmp exnul ! 7768: 0: ! 7769: # ! 7770: # HERE IF CONVERTED RESULT TO CHECK FOR NULL STRING ! 7771: # ! 7772: befa8: cmpl r7,$num01 # jump if not a string ! 7773: bnequ befc8 ! 7774: tstl 4*sclen(r9) # return null if null ! 7775: bnequ 0f ! 7776: jmp exnul ! 7777: 0: ! 7778: # ! 7779: # RETURN IF RESULT IS IN DYNAMIC STORAGE ! 7780: # ! 7781: befc8: cmpl r9,dnamb # jump if not in dynamic storage ! 7782: blssu befc9 ! 7783: cmpl r9,dnamp # return result if already dynamic ! 7784: bgtru 0f ! 7785: jmp exixr ! 7786: 0: ! 7787: # ! 7788: # HERE WE COPY A RESULT INTO THE DYNAMIC REGION ! 7789: # ! 7790: befc9: movl (r9),r6 # get possible type word ! 7791: tstl r7 # jump if unconverted result ! 7792: beqlu bef11 ! 7793: movl $b$scl,r6 # string ! 7794: cmpl r7,$num01 # yes jump ! 7795: beqlu bef10 ! 7796: movl $b$icl,r6 # integer ! 7797: cmpl r7,$num02 # yes jump ! 7798: beqlu bef10 ! 7799: movl $b$rcl,r6 # real ! 7800: # ! 7801: # STORE TYPE WORD IN RESULT ! 7802: # ! 7803: bef10: movl r6,(r9) # stored before copying to dynamic ! 7804: # ! 7805: # MERGE FOR UNCONVERTED RESULT ! 7806: # ! 7807: bef11: jsb blkln # get length of block ! 7808: movl r9,r10 # copy address of old block ! 7809: jsb alloc # allocate dynamic block same size ! 7810: movl r9,-(sp) # set pointer to new block as result ! 7811: jsb sbmvw # copy old block to dynamic block ! 7812: jmp exits # exit with result on stack ! 7813: #page ! 7814: # ! 7815: # EVBLK ! 7816: # ! 7817: # THE ROUTINE FOR AN EVBLK IS NEVER EXECUTED ! 7818: # ! 7819: .align 2 ! 7820: .word bl$ev ! 7821: b$evt: # entry point (evblk) ! 7822: #page ! 7823: # ! 7824: # FFBLK ! 7825: # ! 7826: # THE ROUTINE FOR AN FFBLK IS EXECUTED FROM THE O$FNC ENTRY ! 7827: # TO CALL A FIELD FUNCTION AND EXTRACT A FIELD VALUE/NAME. ! 7828: # ! 7829: # (XL) POINTER TO FFBLK ! 7830: # ! 7831: .align 2 ! 7832: .word bl$ff ! 7833: b$ffc: # entry point (ffblk) ! 7834: movl r10,r9 # copy ffblk pointer ! 7835: movl (r3)+,r8 # load next code word ! 7836: movl (sp),r10 # load pdblk pointer ! 7837: cmpl (r10),$b$pdt # jump if not pdblk at all ! 7838: bnequ bffc2 ! 7839: movl 4*pddfp(r10),r6 # load dfblk pointer from pdblk ! 7840: # ! 7841: # LOOP TO FIND CORRECT FFBLK FOR THIS PDBLK ! 7842: # ! 7843: bffc1: cmpl r6,4*ffdfp(r9) # jump if this is the correct ffblk ! 7844: beqlu bffc3 ! 7845: movl 4*ffnxt(r9),r9 # else link to next ffblk on chain ! 7846: tstl r9 # loop back if another entry to check ! 7847: bnequ bffc1 ! 7848: # ! 7849: # HERE FOR BAD ARGUMENT ! 7850: # ! 7851: bffc2: jmp er_041 # field function argument is wrong datatype ! 7852: #page ! 7853: # ! 7854: # FFBLK (CONTINUED) ! 7855: # ! 7856: # HERE AFTER LOCATING CORRECT FFBLK ! 7857: # ! 7858: bffc3: movl 4*ffofs(r9),r6 # load field offset ! 7859: cmpl r8,$ofne$ # jump if called by name ! 7860: beqlu bffc5 ! 7861: addl2 r6,r10 # else point to value field ! 7862: movl (r10),r9 # load value ! 7863: cmpl (r9),$b$trt # jump if not trapped ! 7864: bnequ bffc4 ! 7865: subl2 r6,r10 # else restore name base,offset ! 7866: movl r8,(sp) # save next code word over pdblk ptr ! 7867: jsb acess # access value ! 7868: .long exfal # fail if access fails ! 7869: movl (sp),r8 # restore next code word ! 7870: # ! 7871: # HERE AFTER GETTING VALUE IN (XR) ! 7872: # ! 7873: bffc4: movl r9,(sp) # store value on stack (over pdblk) ! 7874: movl r8,r9 # copy next code word ! 7875: movl (r9),r10 # load entry address ! 7876: movl r10,r11 # jump to routine for next code word ! 7877: jmp (r11) ! 7878: # ! 7879: # HERE IF CALLED BY NAME ! 7880: # ! 7881: bffc5: movl r6,-(sp) # store name offset (base is set) ! 7882: jmp exits # exit with name on stack ! 7883: #page ! 7884: # ! 7885: # ICBLK ! 7886: # ! 7887: # THE ROUTINE FOR ICBLK IS EXECUTED FROM THE GENERATED ! 7888: # CODE TO LOAD AN INTEGER VALUE ONTO THE STACK. ! 7889: # ! 7890: # (XR) POINTER TO ICBLK ! 7891: # ! 7892: .align 2 ! 7893: .word bl$ic ! 7894: b$icl: # entry point (icblk) ! 7895: jmp exixr # stack xr and obey next code word ! 7896: #page ! 7897: # ! 7898: # KVBLK ! 7899: # ! 7900: # THE ROUTINE FOR A KVBLK IS NEVER EXECUTED. ! 7901: # ! 7902: .align 2 ! 7903: .word bl$kv ! 7904: b$kvt: # entry point (kvblk) ! 7905: #page ! 7906: # ! 7907: # NMBLK ! 7908: # ! 7909: # THE ROUTINE FOR A NMBLK IS EXECUTED FROM THE GENERATED ! 7910: # CODE FOR THE CASE OF LOADING A NAME ONTO THE STACK ! 7911: # WHERE THE NAME IS THAT OF A NATURAL VARIABLE WHICH CAN ! 7912: # BE PREEVALUATED AT COMPILE TIME. ! 7913: # ! 7914: # (XR) POINTER TO NMBLK ! 7915: # ! 7916: .align 2 ! 7917: .word bl$nm ! 7918: b$nml: # entry point (nmblk) ! 7919: jmp exixr # stack xr and obey next code word ! 7920: #page ! 7921: # ! 7922: # PDBLK ! 7923: # ! 7924: # THE ROUTINE FOR A PDBLK IS NEVER EXECUTED ! 7925: # ! 7926: .align 2 ! 7927: .word bl$pd ! 7928: b$pdt: # entry point (pdblk) ! 7929: #page ! 7930: # ! 7931: # PFBLK ! 7932: # ! 7933: # THE ROUTINE FOR A PFBLK IS EXECUTED FROM THE ENTRY O$FNC ! 7934: # TO CALL A PROGRAM DEFINED FUNCTION. ! 7935: # ! 7936: # (XL) POINTER TO PFBLK ! 7937: # ! 7938: # THE FOLLOWING STACK ENTRIES ARE MADE BEFORE PASSING ! 7939: # CONTROL TO THE PROGRAM DEFINED FUNCTION. ! 7940: # ! 7941: # SAVED VALUE OF FIRST ARGUMENT ! 7942: # . ! 7943: # SAVED VALUE OF LAST ARGUMENT ! 7944: # SAVED VALUE OF FIRST LOCAL ! 7945: # . ! 7946: # SAVED VALUE OF LAST LOCAL ! 7947: # SAVED VALUE OF FUNCTION NAME ! 7948: # SAVED CODE BLOCK PTR (R$COD) ! 7949: # SAVED CODE POINTER (-R$COD) ! 7950: # SAVED VALUE OF FLPRT ! 7951: # SAVED VALUE OF FLPTR ! 7952: # POINTER TO PFBLK ! 7953: # FLPTR --------------- ZERO (TO BE OVERWRITTEN WITH OFFS) ! 7954: # ! 7955: .align 2 ! 7956: .word bl$pf ! 7957: b$pfc: # entry point (pfblk) ! 7958: movl r10,bpfpf # save pfblk ptr (need not be reloc) ! 7959: movl r10,r9 # copy for the moment ! 7960: movl 4*pfvbl(r9),r10 # point to vrblk for function ! 7961: # ! 7962: # LOOP TO FIND OLD VALUE OF FUNCTION ! 7963: # ! 7964: bpf01: movl r10,r7 # save pointer ! 7965: movl 4*vrval(r10),r10# load value ! 7966: cmpl (r10),$b$trt # loop if trblk ! 7967: beqlu bpf01 ! 7968: # ! 7969: # SET VALUE TO NULL AND SAVE OLD FUNCTION VALUE ! 7970: # ! 7971: movl r10,bpfsv # save old value ! 7972: movl r7,r10 # point back to block with value ! 7973: movl $nulls,4*vrval(r10) # set value to null ! 7974: movl 4*fargs(r9),r6 # load number of arguments ! 7975: addl2 $4*pfarg,r9 # point to pfarg entries ! 7976: tstl r6 # jump if no arguments ! 7977: beqlu bpf04 ! 7978: movl sp,r10 # ptr to last arg ! 7979: moval 0[r6],r6 # convert no. of args to bytes offset ! 7980: addl2 r6,r10 # point before first arg ! 7981: movl r10,bpfxt # remember arg pointer ! 7982: #page ! 7983: # ! 7984: # PFBLK (CONTINUED) ! 7985: # ! 7986: # LOOP TO SAVE OLD ARGUMENT VALUES AND SET NEW ONES ! 7987: # ! 7988: bpf02: movl (r9)+,r10 # load vrblk ptr for next argument ! 7989: # ! 7990: # LOOP THROUGH POSSIBLE TRBLK CHAIN TO FIND VALUE ! 7991: # ! 7992: bpf03: movl r10,r8 # save pointer ! 7993: movl 4*vrval(r10),r10# load next value ! 7994: cmpl (r10),$b$trt # loop back if trblk ! 7995: beqlu bpf03 ! 7996: # ! 7997: # SAVE OLD VALUE AND GET NEW VALUE ! 7998: # ! 7999: movl r10,r6 # keep old value ! 8000: movl bpfxt,r10 # point before next stacked arg ! 8001: movl -(r10),r7 # load argument (new value) ! 8002: movl r6,(r10) # save old value ! 8003: movl r10,bpfxt # keep arg ptr for next time ! 8004: movl r8,r10 # point back to block with value ! 8005: movl r7,4*vrval(r10) # set new value ! 8006: cmpl sp,bpfxt # loop if not all done ! 8007: bnequ bpf02 ! 8008: # ! 8009: # NOW PROCESS LOCALS ! 8010: # ! 8011: bpf04: movl bpfpf,r10 # restore pfblk pointer ! 8012: movl 4*pfnlo(r10),r6 # load number of locals ! 8013: tstl r6 # jump if no locals ! 8014: beqlu bpf07 ! 8015: movl $nulls,r7 # get null constant ! 8016: # set local counter ! 8017: # ! 8018: # LOOP TO PROCESS LOCALS ! 8019: # ! 8020: bpf05: movl (r9)+,r10 # load vrblk ptr for next local ! 8021: # ! 8022: # LOOP THROUGH POSSIBLE TRBLK CHAIN TO FIND VALUE ! 8023: # ! 8024: bpf06: movl r10,r8 # save pointer ! 8025: movl 4*vrval(r10),r10# load next value ! 8026: cmpl (r10),$b$trt # loop back if trblk ! 8027: beqlu bpf06 ! 8028: # ! 8029: # SAVE OLD VALUE AND SET NULL AS NEW VALUE ! 8030: # ! 8031: movl r10,-(sp) # stack old value ! 8032: movl r8,r10 # point back to block with value ! 8033: movl r7,4*vrval(r10) # set null as new value ! 8034: sobgtr r6,bpf05 # loop till all locals processed ! 8035: #page ! 8036: # ! 8037: # PFBLK (CONTINUED) ! 8038: # ! 8039: # HERE AFTER PROCESSING ARGUMENTS AND LOCALS ! 8040: # ! 8041: bpf07: clrl r9 # zero reg xr in case ! 8042: tstl kvpfl # skip if profiling is off ! 8043: beqlu bpf7c ! 8044: cmpl kvpfl,$num02 # branch on type of profile ! 8045: beqlu bpf7a ! 8046: # ! 8047: # HERE IF &PROFILE = 1 ! 8048: # ! 8049: jsb systm # get current time ! 8050: movl r5,pfetm # save for a sec ! 8051: subl2 pfstm,r5 # find time used by caller ! 8052: jsb icbld # build into an icblk ! 8053: movl pfetm,r5 # reload current time ! 8054: jmp bpf7b # merge ! 8055: # ! 8056: # HERE IF &PROFILE = 2 ! 8057: # ! 8058: bpf7a: movl pfstm,r5 # get start time of calling stmt ! 8059: jsb icbld # assemble an icblk round it ! 8060: jsb systm # get now time ! 8061: # ! 8062: # BOTH TYPES OF PROFILE MERGE HERE ! 8063: # ! 8064: bpf7b: movl r5,pfstm # set start time of 1st func stmt ! 8065: movl sp,pffnc # flag function entry ! 8066: # ! 8067: # NO PROFILING MERGES HERE ! 8068: # ! 8069: bpf7c: movl r9,-(sp) # stack icblk ptr (or zero) ! 8070: movl r$cod,r6 # load old code block pointer ! 8071: movl r3,r7 # get code pointer ! 8072: subl2 r6,r7 # make code pointer into offset ! 8073: movl bpfpf,r10 # recall pfblk pointer ! 8074: movl bpfsv,-(sp) # stack old value of function name ! 8075: movl r6,-(sp) # stack code block pointer ! 8076: movl r7,-(sp) # stack code offset ! 8077: movl flprt,-(sp) # stack old flprt ! 8078: movl flptr,-(sp) # stack old failure pointer ! 8079: movl r10,-(sp) # stack pointer to pfblk ! 8080: clrl -(sp) # dummy zero entry for fail return ! 8081: jsb sbchk # check for stack overflow ! 8082: movl sp,flptr # set new fail return value ! 8083: movl sp,flprt # set new flprt ! 8084: movl kvtra,r6 # load trace value ! 8085: addl2 kvftr,r6 # add ftrace value ! 8086: tstl r6 # jump if tracing possible ! 8087: bnequ bpf09 ! 8088: incl kvfnc # else bump fnclevel ! 8089: # ! 8090: # HERE TO ACTUALLY JUMP TO FUNCTION ! 8091: # ! 8092: bpf08: movl 4*pfcod(r10),r9 # point to code ! 8093: movl (r9),r11 # off to execute function ! 8094: jmp (r11) ! 8095: # ! 8096: # HERE IF TRACING IS POSSIBLE ! 8097: # ! 8098: bpf09: movl 4*pfctr(r10),r9 # load possible call trace trblk ! 8099: movl 4*pfvbl(r10),r10# load vrblk pointer for function ! 8100: movl $4*vrval,r6 # set name offset for variable ! 8101: tstl kvtra # jump if trace mode is off ! 8102: beqlu bpf10 ! 8103: tstl r9 # or if there is no call trace ! 8104: beqlu bpf10 ! 8105: # ! 8106: # HERE IF CALL TRACED ! 8107: # ! 8108: decl kvtra # decrement trace count ! 8109: tstl 4*trfnc(r9) # jump if print trace ! 8110: beqlu bpf11 ! 8111: jsb trxeq # execute function type trace ! 8112: #page ! 8113: # ! 8114: # PFBLK (CONTINUED) ! 8115: # ! 8116: # HERE TO TEST FOR FTRACE TRACE ! 8117: # ! 8118: bpf10: tstl kvftr # jump if ftrace is off ! 8119: beqlu bpf16 ! 8120: decl kvftr # else decrement ftrace ! 8121: # ! 8122: # HERE FOR PRINT TRACE ! 8123: # ! 8124: bpf11: jsb prtsn # print statement number ! 8125: jsb prtnm # print function name ! 8126: movl $ch$pp,r6 # load left paren ! 8127: jsb prtch # print left paren ! 8128: movl 4*1(sp),r10 # recover pfblk pointer ! 8129: tstl 4*fargs(r10) # skip if no arguments ! 8130: beqlu bpf15 ! 8131: clrl r7 # else set argument counter ! 8132: jmp bpf13 # jump into loop ! 8133: # ! 8134: # LOOP TO PRINT ARGUMENT VALUES ! 8135: # ! 8136: bpf12: movl $ch$cm,r6 # load comma ! 8137: jsb prtch # print to separate from last arg ! 8138: # ! 8139: # MERGE HERE FIRST TIME (NO COMMA REQUIRED) ! 8140: # ! 8141: bpf13: movl r7,(sp) # save arg ctr (over failoffs is ok) ! 8142: moval 0[r7],r7 # convert to byte offset ! 8143: addl2 r7,r10 # point to next argument pointer ! 8144: movl 4*pfarg(r10),r9 # load next argument vrblk ptr ! 8145: subl2 r7,r10 # restore pfblk pointer ! 8146: movl 4*vrval(r9),r9 # load next value ! 8147: jsb prtvl # print argument value ! 8148: #page ! 8149: # ! 8150: # HERE AFTER DEALING WITH ONE ARGUMENT ! 8151: # ! 8152: movl (sp),r7 # restore argument counter ! 8153: incl r7 # increment argument counter ! 8154: cmpl r7,4*fargs(r10) # loop if more to print ! 8155: blssu bpf12 ! 8156: # ! 8157: # MERGE HERE IN NO ARGS CASE TO PRINT PAREN ! 8158: # ! 8159: bpf15: movl $ch$rp,r6 # load right paren ! 8160: jsb prtch # print to terminate output ! 8161: jsb prtnl # terminate print line ! 8162: # ! 8163: # MERGE HERE TO EXIT WITH TEST FOR FNCLEVEL TRACE ! 8164: # ! 8165: bpf16: incl kvfnc # increment fnclevel ! 8166: movl r$fnc,r10 # load ptr to possible trblk ! 8167: jsb ktrex # call keyword trace routine ! 8168: # ! 8169: # CALL FUNCTION AFTER TRACE TESTS COMPLETE ! 8170: # ! 8171: movl 4*1(sp),r10 # restore pfblk pointer ! 8172: jmp bpf08 # jump back to execute function ! 8173: #page ! 8174: # ! 8175: # RCBLK ! 8176: # ! 8177: # THE ROUTINE FOR AN RCBLK IS EXECUTED FROM THE GENERATED ! 8178: # CODE TO LOAD A REAL VALUE ONTO THE STACK. ! 8179: # ! 8180: # (XR) POINTER TO RCBLK ! 8181: # ! 8182: .align 2 ! 8183: .word bl$rc ! 8184: b$rcl: # entry point (rcblk) ! 8185: jmp exixr # stack xr and obey next code word ! 8186: #page ! 8187: # ! 8188: # SCBLK ! 8189: # ! 8190: # THE ROUTINE FOR AN SCBLK IS EXECUTED FROM THE GENERATED ! 8191: # CODE TO LOAD A STRING VALUE ONTO THE STACK. ! 8192: # ! 8193: # (XR) POINTER TO SCBLK ! 8194: # ! 8195: .align 2 ! 8196: .word bl$sc ! 8197: b$scl: # entry point (scblk) ! 8198: jmp exixr # stack xr and obey next code word ! 8199: #page ! 8200: # ! 8201: # TBBLK ! 8202: # ! 8203: # THE ROUTINE FOR A TBBLK IS NEVER EXECUTED ! 8204: # ! 8205: .align 2 ! 8206: .word bl$tb ! 8207: b$tbt: # entry point (tbblk) ! 8208: #page ! 8209: # ! 8210: # TEBLK ! 8211: # ! 8212: # THE ROUTINE FOR A TEBLK IS NEVER EXECUTED ! 8213: # ! 8214: .align 2 ! 8215: .word bl$te ! 8216: b$tet: # entry point (teblk) ! 8217: #page ! 8218: # ! 8219: # VCBLK ! 8220: # ! 8221: # THE ROUTINE FOR A VCBLK IS NEVER EXECUTED ! 8222: # ! 8223: .align 2 ! 8224: .word bl$vc ! 8225: b$vct: # entry point (vcblk) ! 8226: #page ! 8227: # ! 8228: # VRBLK ! 8229: # ! 8230: # THE VRBLK ROUTINES ARE EXECUTED FROM THE GENERATED CODE. ! 8231: # THERE ARE SIX ENTRIES FOR VRBLK COVERING VARIOUS CASES ! 8232: # ! 8233: .align 2 ! 8234: .word bl$$i ! 8235: b$vr$: # mark start of vrblk entry points ! 8236: # ! 8237: # ENTRY FOR VRGET (TRAPPED CASE). THIS ROUTINE IS CALLED ! 8238: # FROM THE GENERATED CODE TO LOAD THE VALUE OF A VARIABLE. ! 8239: # THIS ENTRY POINT IS USED IF AN ACCESS TRACE OR INPUT ! 8240: # ASSOCIATION IS CURRENTLY ACTIVE. ! 8241: # ! 8242: # (XR) POINTER TO VRGET FIELD OF VRBLK ! 8243: # ! 8244: .align 2 ! 8245: .word bl$$i ! 8246: b$vra: # entry point ! 8247: movl r9,r10 # copy name base (vrget = 0) ! 8248: movl $4*vrval,r6 # set name offset ! 8249: jsb acess # access value ! 8250: .long exfal # fail if access fails ! 8251: jmp exixr # else exit with result in xr ! 8252: #page ! 8253: # ! 8254: # VRBLK (CONTINUED) ! 8255: # ! 8256: # ENTRY FOR VRSTO (ERROR CASE. THIS ROUTINE IS CALLED FROM ! 8257: # THE EXECUTED CODE FOR AN ATTEMPT TO MODIFY THE VALUE ! 8258: # OF A PROTECTED (PATTERN VALUED) NATURAL VARIABLE. ! 8259: # ! 8260: b$vre: # entry point ! 8261: jmp er_042 # attempt to change value of protected variable ! 8262: #page ! 8263: # ! 8264: # VRBLK (CONTINUED) ! 8265: # ! 8266: # ENTRY FOR VRTRA (UNTRAPPED CASE). THIS ROUTINE IS CALLED ! 8267: # FROM THE EXECUTED CODE TO TRANSFER TO A LABEL. ! 8268: # ! 8269: # (XR) POINTER TO VRTRA FIELD OF VRBLK ! 8270: # ! 8271: b$vrg: # entry point ! 8272: movl 4*vrlbo(r9),r9 # load code pointer ! 8273: movl (r9),r10 # load entry address ! 8274: movl r10,r11 # jump to routine for next code word ! 8275: jmp (r11) ! 8276: #page ! 8277: # ! 8278: # VRBLK (CONTINUED) ! 8279: # ! 8280: # ENTRY FOR VRGET (UNTRAPPED CASE). THIS ROUTINE IS CALLED ! 8281: # FROM THE GENERATED CODE TO LOAD THE VALUE OF A VARIABLE. ! 8282: # ! 8283: # (XR) POINTS TO VRGET FIELD OF VRBLK ! 8284: # ! 8285: b$vrl: # entry point ! 8286: movl 4*vrval(r9),-(sp)# load value onto stack (vrget = 0) ! 8287: jmp exits # obey next code word ! 8288: #page ! 8289: # ! 8290: # VRBLK (CONTINUED) ! 8291: # ! 8292: # ENTRY FOR VRSTO (UNTRAPPED CASE). THIS ROUTINE IS CALLED ! 8293: # FROM THE GENERATED CODE TO STORE THE VALUE OF A VARIABLE. ! 8294: # ! 8295: # (XR) POINTER TO VRSTO FIELD OF VRBLK ! 8296: # ! 8297: b$vrs: # entry point ! 8298: movl (sp),4*vrvlo(r9)# store value, leave on stack ! 8299: jmp exits # obey next code word ! 8300: #page ! 8301: # ! 8302: # VRBLK (CONTINUED) ! 8303: # ! 8304: # VRTRA (TRAPPED CASE). THIS ROUTINE IS CALLED FROM THE ! 8305: # GENERATED CODE TO TRANSFER TO A LABEL WHEN A LABEL ! 8306: # TRACE IS CURRENTLY ACTIVE. ! 8307: # ! 8308: b$vrt: # entry point ! 8309: subl2 $4*vrtra,r9 # point back to start of vrblk ! 8310: movl r9,r10 # copy vrblk pointer ! 8311: movl $4*vrval,r6 # set name offset ! 8312: movl 4*vrlbl(r10),r9 # load pointer to trblk ! 8313: tstl kvtra # jump if trace is off ! 8314: beqlu bvrt2 ! 8315: decl kvtra # else decrement trace count ! 8316: tstl 4*trfnc(r9) # jump if print trace case ! 8317: beqlu bvrt1 ! 8318: jsb trxeq # else execute full trace ! 8319: jmp bvrt2 # merge to jump to label ! 8320: # ! 8321: # HERE FOR PRINT TRACE -- PRINT COLON ( LABEL NAME ) ! 8322: # ! 8323: bvrt1: jsb prtsn # print statement number ! 8324: movl r10,r9 # copy vrblk pointer ! 8325: movl $ch$cl,r6 # colon ! 8326: jsb prtch # print it ! 8327: movl $ch$pp,r6 # left paren ! 8328: jsb prtch # print it ! 8329: jsb prtvn # print label name ! 8330: movl $ch$rp,r6 # right paren ! 8331: jsb prtch # print it ! 8332: jsb prtnl # terminate line ! 8333: movl 4*vrlbl(r10),r9 # point back to trblk ! 8334: # ! 8335: # MERGE HERE TO JUMP TO LABEL ! 8336: # ! 8337: bvrt2: movl 4*trlbl(r9),r9 # load pointer to actual code ! 8338: movl (r9),r11 # execute statement at label ! 8339: jmp (r11) ! 8340: #page ! 8341: # ! 8342: # VRBLK (CONTINUED) ! 8343: # ! 8344: # ENTRY FOR VRSTO (TRAPPED CASE). THIS ROUTINE IS CALLED ! 8345: # FROM THE GENERATED CODE TO STORE THE VALUE OF A VARIABLE. ! 8346: # THIS ENTRY IS USED WHEN A VALUE TRACE OR OUTPUT ! 8347: # ASSOCIATION IS CURRENTLY ACTIVE. ! 8348: # ! 8349: # (XR) POINTER TO VRSTO FIELD OF VRBLK ! 8350: # ! 8351: b$vrv: # entry point ! 8352: movl (sp),r7 # load value (leave copy on stack) ! 8353: subl2 $4*vrsto,r9 # point to vrblk ! 8354: movl r9,r10 # copy vrblk pointer ! 8355: movl $4*vrval,r6 # set offset ! 8356: jsb asign # call assignment routine ! 8357: .long exfal # fail if assignment fails ! 8358: jmp exits # else return with result on stack ! 8359: #page ! 8360: # ! 8361: # XNBLK ! 8362: # ! 8363: # THE ROUTINE FOR AN XNBLK IS NEVER EXECUTED ! 8364: # ! 8365: .align 2 ! 8366: .word bl$xn ! 8367: b$xnt: # entry point (xnblk) ! 8368: #page ! 8369: # ! 8370: # XRBLK ! 8371: # ! 8372: # THE ROUTINE FOR AN XRBLK IS NEVER EXECUTED ! 8373: # ! 8374: .align 2 ! 8375: .word bl$xr ! 8376: b$xrt: # entry point (xrblk) ! 8377: # ! 8378: # MARK ENTRY ADDRESS PAST LAST BLOCK ACTION ROUTINE ! 8379: # ! 8380: .align 2 ! 8381: .word bl$$i ! 8382: b$yyy: # last block routine entry point ! 8383: #title s p i t b o l -- pattern matching routines ! 8384: # ! 8385: # THE FOLLOWING SECTION CONSISTS OF THE PATTERN MATCHING ! 8386: # ROUTINES. ALL PATTERN NODES CONTAIN A POINTER (PCODE) ! 8387: # TO ONE OF THE ROUTINES IN THIS SECTION (P$XXX). ! 8388: # ! 8389: # NOTE THAT THIS SECTION FOLLOWS THE B$XXX ROUTINES TO ! 8390: # ENABLE A FAST TEST FOR THE PATTERN DATATYPE. ! 8391: # ! 8392: .align 2 ! 8393: .word bl$$i ! 8394: p$aaa: # entry to mark first pattern ! 8395: # ! 8396: # ! 8397: # THE ENTRY CONDITIONS TO THE MATCH ROUTINE ARE AS FOLLOWS ! 8398: # (SEE O$PMN, O$PMV, O$PMS AND PROCEDURE MATCH). ! 8399: # ! 8400: # STACK CONTENTS. ! 8401: # ! 8402: # NAME BASE (O$PMN ONLY) ! 8403: # NAME OFFSET (O$PMN ONLY) ! 8404: # TYPE (0-O$PMN, 1-O$PMV, 2-O$PMS) ! 8405: # PMHBS --------------- INITIAL CURSOR (ZERO) ! 8406: # INITIAL NODE POINTER ! 8407: # XS ------------------ =NDABO (ANCHORED), =NDUNA (UNANCH) ! 8408: # ! 8409: # REGISTER VALUES. ! 8410: # ! 8411: # (XS) SET AS SHOWN IN STACK DIAGRAM ! 8412: # (XR) POINTER TO INITIAL PATTERN NODE ! 8413: # (WB) INITIAL CURSOR (ZERO) ! 8414: # ! 8415: # GLOBAL PATTERN VALUES ! 8416: # ! 8417: # R$PMS POINTER TO SUBJECT STRING SCBLK ! 8418: # PMSSL LENGTH OF SUBJECT STRING IN CHARS ! 8419: # PMDFL DOT FLAG, INITIALLY ZERO ! 8420: # PMHBS SET AS SHOWN IN STACK DIAGRAM ! 8421: # ! 8422: # CONTROL IS PASSED BY BRANCHING THROUGH THE PCODE ! 8423: # FIELD OF THE INITIAL PATTERN NODE (BRI (XR)). ! 8424: #page ! 8425: # ! 8426: # DESCRIPTION OF ALGORITHM ! 8427: # ! 8428: # A PATTERN STRUCTURE IS REPRESENTED AS A LINKED GRAPH ! 8429: # OF NODES WITH THE FOLLOWING STRUCTURE. ! 8430: # ! 8431: # +------------------------------------+ ! 8432: # I PCODE I ! 8433: # +------------------------------------+ ! 8434: # I PTHEN I ! 8435: # +------------------------------------+ ! 8436: # I PARM1 I ! 8437: # +------------------------------------+ ! 8438: # I PARM2 I ! 8439: # +------------------------------------+ ! 8440: # ! 8441: # PCODE IS A POINTER TO THE ROUTINE WHICH WILL PERFORM ! 8442: # THE MATCH OF THIS PARTICULAR NODE TYPE. ! 8443: # ! 8444: # PTHEN IS A POINTER TO THE SUCCESSOR NODE. I.E. THE NODE ! 8445: # TO BE MATCHED IF THE ATTEMPT TO MATCH THIS NODE SUCCEEDS. ! 8446: # IF THIS IS THE LAST NODE OF THE PATTERN PTHEN POINTS ! 8447: # TO THE DUMMY NODE NDNTH WHICH INITIATES PATTERN EXIT. ! 8448: # ! 8449: # PARM1, PARM2 ARE PARAMETERS WHOSE USE VARIES WITH THE ! 8450: # PARTICULAR NODE. THEY ARE ONLY PRESENT IF REQUIRED. ! 8451: # ! 8452: # ALTERNATIVES ARE HANDLED WITH THE SPECIAL ALTERNATIVE ! 8453: # NODE WHOSE PARAMETER POINTS TO THE NODE TO BE MATCHED ! 8454: # IF THERE IS A FAILURE ON THE SUCCESSOR PATH. ! 8455: # ! 8456: # THE FOLLOWING EXAMPLE ILLUSTRATES THE MANNER IN WHICH ! 8457: # THE STRUCTURE IS BUILT UP. THE PATTERN IS ! 8458: # ! 8459: # (A / B / C) (D / E) WHERE / IS ALTERNATION ! 8460: # ! 8461: # IN THE DIAGRAM, THE NODE MARKED + REPRESENTS AN ! 8462: # ALTERNATIVE NODE AND THE DOTTED LINE FROM A + NODE ! 8463: # REPRESENTS THE PARAMETER POINTER TO THE ALTERNATIVE. ! 8464: # ! 8465: # +---+ +---+ +---+ +---+ ! 8466: # I + I-----I A I-----I + I-----I D I----- ! 8467: # +---+ +---+ I +---+ +---+ ! 8468: # . I . ! 8469: # . I . ! 8470: # +---+ +---+ I +---+ ! 8471: # I + I-----I B I--I I E I----- ! 8472: # +---+ +---+ I +---+ ! 8473: # . I ! 8474: # . I ! 8475: # +---+ I ! 8476: # I C I------------I ! 8477: # +---+ ! 8478: #page ! 8479: # ! 8480: # DURING THE MATCH, THE REGISTERS ARE USED AS FOLLOWS. ! 8481: # ! 8482: # (XR) POINTS TO THE CURRENT NODE ! 8483: # (XL) SCRATCH ! 8484: # (XS) MAIN STACK POINTER ! 8485: # (WB) CURSOR (NUMBER OF CHARS MATCHED) ! 8486: # (WA,WC) SCRATCH ! 8487: # ! 8488: # TO KEEP TRACK OF ALTERNATIVES, THE MAIN STACK IS USED AS ! 8489: # A HISTORY STACK AND CONTAINS TWO WORD ENTRIES. ! 8490: # ! 8491: # WORD 1 SAVED CURSOR VALUE ! 8492: # WORD 2 NODE TO MATCH ON FAILURE ! 8493: # ! 8494: # WHEN A FAILURE OCCURS, THE MOST RECENT ENTRY ON THIS ! 8495: # STACK IS POPPED OFF TO RESTORE THE CURSOR AND POINT ! 8496: # TO THE NODE TO BE MATCHED AS AN ALTERNATIVE. THE ENTRY ! 8497: # AT THE BOTTOM OF THE STACK POINTS TO THE FOLLOWING ! 8498: # SPECIAL NODES DEPENDING ON THE SCAN MODE. ! 8499: # ! 8500: # ANCHORED MODE THE BOTTOM ENTRY POINTS TO THE ! 8501: # SPECIAL NODE NDABO WHICH CAUSES AN ! 8502: # ABORT. THE CURSOR VALUE STORED ! 8503: # WITH THIS ENTRY IS ALWAYS ZERO. ! 8504: # ! 8505: # UNANCHORED MODE THE BOTTOM ENTRY POINTS TO THE ! 8506: # SPECIAL NODE NDUNA WHICH MOVES THE ! 8507: # ANCHOR POINT AND RESTARTS THE MATCH ! 8508: # THE CURSOR SAVED WITH THIS ENTRY ! 8509: # IS THE NUMBER OF CHARACTERS WHICH ! 8510: # LIE BEFORE THE INITIAL ANCHOR POINT ! 8511: # (I.E. THE NUMBER OF ANCHOR MOVES). ! 8512: # THIS ENTRY IS THREE WORDS LONG AND ! 8513: # ALSO CONTAINS THE INITIAL PATTERN. ! 8514: # ! 8515: # ENTRIES ARE MADE ON THIS HISTORY STACK BY ALTERNATIVE ! 8516: # NODES AND BY SOME SPECIAL COMPOUD PATTERNS AS DESCRIBED ! 8517: # LATER ON. THE FOLLOWING GLOBAL LOCATIONS ARE USED DURING ! 8518: # PATTERN MATCHING. ! 8519: # ! 8520: # R$PMS POINTER TO SUBJECT STRING ! 8521: # PMSSL LENGTH OF SUBJECT STRING ! 8522: # PMDFL FLAG SET NON-ZERO FOR DOT PATTERNS ! 8523: # PMHBS BASE PTR FOR CURRENT HISTORY STACK ! 8524: # ! 8525: # THE FOLLOWING EXIT POINTS ARE AVAILABLE TO MATCH ROUTINES ! 8526: # ! 8527: # SUCCP SUCCESS IN MATCHING CURRENT NODE ! 8528: # FAILP FAILURE IN MATCHING CURRENT NODE ! 8529: #page ! 8530: # ! 8531: # COMPOUND PATTERNS ! 8532: # ! 8533: # SOME PATTERNS HAVE IMPLICIT ALTERNATIVES AND THEIR ! 8534: # REPRESENTATION IN THE PATTERN STRUCTURE CONSISTS OF A ! 8535: # LINKED SET OF NODES AS INDICATED BY THESE DIAGRAMS. ! 8536: # ! 8537: # AS BEFORE, THE + REPRESENTS AN ALTERNATIVE NODE AND ! 8538: # THE DOTTED LINE FROM A + NODE IS THE PARAMETER POINTER ! 8539: # TO THE ALTERNATIVE PATTERN. ! 8540: # ! 8541: # ARB ! 8542: # --- ! 8543: # ! 8544: # +---+ THIS NODE (P$ARB) MATCHES NULL ! 8545: # I B I----- AND STACKS CURSOR, SUCCESSOR PTR, ! 8546: # +---+ CURSOR (COPY) AND A PTR TO NDARC. ! 8547: # ! 8548: # ! 8549: # ! 8550: # ! 8551: # BAL ! 8552: # --- ! 8553: # ! 8554: # +---+ THE P$BAL NODE SCANS A BALANCED ! 8555: # I B I----- STRING AND THEN STACKS A POINTER ! 8556: # +---+ TO ITSELF ON THE HISTORY STACK. ! 8557: #page ! 8558: # ! 8559: # COMPOUND PATTERN STRUCTURES (CONTINUED) ! 8560: # ! 8561: # ! 8562: # ARBNO ! 8563: # ----- ! 8564: # ! 8565: # +---+ THIS ALTERNATIVE NODE MATCHES NULL ! 8566: # +----I + I----- THE FIRST TIME AND STACKS A POINTER ! 8567: # I +---+ TO THE ARGUMENT PATTERN X. ! 8568: # I . ! 8569: # I . ! 8570: # I +---+ NODE (P$ABA) TO STACK CURSOR ! 8571: # I I A I AND HISTORY STACK BASE PTR. ! 8572: # I +---+ ! 8573: # I I ! 8574: # I I ! 8575: # I +---+ THIS IS THE ARGUMENT PATTERN. AS ! 8576: # I I X I INDICATED, THE SUCCESSOR OF THE ! 8577: # I +---+ PATTERN IS THE P$ABC NODE ! 8578: # I I ! 8579: # I I ! 8580: # I +---+ THIS NODE (P$ABC) POPS PMHBS, ! 8581: # +----I C I STACKS OLD PMHBS AND PTR TO NDABD ! 8582: # +---+ (UNLESS OPTIMISATION HAS OCCURRED) ! 8583: # ! 8584: # STRUCTURE AND EXECUTION OF THIS PATTERN RESEMBLE THOSE OF ! 8585: # RECURSIVE PATTERN MATCHING AND IMMEDIATE ASSIGNMENT. ! 8586: # THE ALTERNATIVE NODE AT THE HEAD OF THE STRUCTURE MATCHES ! 8587: # NULL INITIALLY BUT ON SUBSEQUENT FAILURE ENSURES ATTEMPT ! 8588: # TO MATCH THE ARGUMENT. BEFORE THE ARGUMENT IS MATCHED ! 8589: # P$ABA STACKS THE CURSOR,PMHBS AND A PTR TO P$ABB. IF ! 8590: # THE ARGUMENT CANT BE MATCHED , P$ABB REMOVES THIS SPECIAL ! 8591: # STACK ENTRY AND FAILS. ! 8592: # IF ARGUMENT IS MATCHED , P$ABC RESTORES THE OUTER PMHBS ! 8593: # VALUE (SAVED BY P$ABA) . THEN IF THE ARGUMENT HAS LEFT ! 8594: # ALTERNATIVES ON STACK IT STACKS THE INNER VALUE OF PMHBS ! 8595: # AND A PTR TO NDABD. IF ARGUMENT LEFT NOTHING ON THE STACK ! 8596: # IT OPTIMISES BY REMOVING ITEMS STACKED BY P$ABA. FINALLY ! 8597: # A CHECK IS MADE THAT ARGUMENT MATCHED MORE THAN THE NULL ! 8598: # STRING (CHECK IS INTENDED TO PREVENT USELESS LOOPING). ! 8599: # IF SO THE SUCCESSOR IS AGAIN THE ALTERNATIVE NODE AT THE ! 8600: # HEAD OF THE STRUCTURE , ENSURING A POSSIBLE EXTRA ATTEMPT ! 8601: # TO MATCH THE ARG IF NECESSARY. IF NOT , THE SUCCESSOR TO ! 8602: # ALTERNATIVE IS TAKEN SO AS TO TERMINATE THE LOOP. P$ABD ! 8603: # RESTORES INNER PMHBS PTR AND FAILS , THUS TRYING TO MATCH ! 8604: # ALTERNATIVES LEFT BY THE ARBNO ARGUMENT. ! 8605: #page ! 8606: # ! 8607: # COMPOUND PATTERN STRUCTURES (CONTINUED) ! 8608: # ! 8609: # BREAKX ! 8610: # ------ ! 8611: # ! 8612: # +---+ THIS NODE IS A BREAK NODE FOR ! 8613: # +----I B I THE ARGUMENT TO BREAKX, IDENTICAL ! 8614: # I +---+ TO AN ORDINARY BREAK NODE. ! 8615: # I I ! 8616: # I I ! 8617: # I +---+ THIS ALTERNATIVE NODE STACKS A ! 8618: # I I + I----- POINTER TO THE BREAKX NODE TO ! 8619: # I +---+ ALLOW FOR SUBSEQUENT FAILURE ! 8620: # I . ! 8621: # I . ! 8622: # I +---+ THIS IS THE BREAKX NODE ITSELF. IT ! 8623: # +----I X I MATCHES ONE CHARACTER AND THEN ! 8624: # +---+ PROCEEDS BACK TO THE BREAK NODE. ! 8625: # ! 8626: # ! 8627: # ! 8628: # ! 8629: # FENCE ! 8630: # ----- ! 8631: # ! 8632: # +---+ THE FENCE NODE MATCHES NULL AND ! 8633: # I F I----- STACKS A POINTER TO NODE NDABO TO ! 8634: # +---+ ABORT ON A SUBSEQUENT REMATCH ! 8635: # ! 8636: # ! 8637: # ! 8638: # ! 8639: # SUCCEED ! 8640: # ------- ! 8641: # ! 8642: # +---+ THE NODE FOR SUCCEED MATCHES NULL ! 8643: # I S I----- AND STACKS A POINTER TO ITSELF ! 8644: # +---+ TO REPEAT THE MATCH ON A FAILURE. ! 8645: #page ! 8646: # ! 8647: # COMPOUND PATTERNS (CONTINUED) ! 8648: # ! 8649: # BINARY DOT (PATTERN ASSIGNMENT) ! 8650: # ------------------------------- ! 8651: # ! 8652: # +---+ THIS NODE (P$PAA) SAVES THE CURRENT ! 8653: # I A I CURSOR AND A POINTER TO THE ! 8654: # +---+ SPECIAL NODE NDPAB ON THE STACK. ! 8655: # I ! 8656: # I ! 8657: # +---+ THIS IS THE STRUCTURE FOR THE ! 8658: # I X I PATTERN LEFT ARGUMENT OF THE ! 8659: # +---+ PATTERN ASSIGNMENT CALL. ! 8660: # I ! 8661: # I ! 8662: # +---+ THIS NODE (P$PAC) SAVES THE CURSOR, ! 8663: # I C I----- A PTR TO ITSELF, THE CURSOR (COPY) ! 8664: # +---+ AND A PTR TO NDPAD ON THE STACK. ! 8665: # ! 8666: # ! 8667: # THE FUNCTION OF THE MATCH ROUTINE FOR NDPAB (P$PAB) ! 8668: # IS SIMPLY TO UNSTACK ITSELF AND FAIL BACK ONTO THE STACK. ! 8669: # ! 8670: # THE MATCH ROUTINE FOR P$PAC ALSO SETS THE GLOBAL PATTERN ! 8671: # FLAG PMDFL NON-ZERO TO INDICATE THAT PATTERN ASSIGNMENTS ! 8672: # MAY HAVE OCCURED IN THE PATTERN MATCH ! 8673: # ! 8674: # IF PMDFL IS SET AT THE END OF THE MATCH (SEE P$NTH), THE ! 8675: # HISTORY STACK IS SCANNED FOR MATCHING NDPAB-NDPAD PAIRS ! 8676: # AND THE CORRESPONDING PATTERN ASSIGNMENTS ARE EXECUTED. ! 8677: # ! 8678: # THE FUNCTION OF THE MATCH ROUTINE FOR NDPAD (P$PAD) ! 8679: # IS SIMPLY TO REMOVE ITS ENTRY FROM THE STACK AND FAIL. ! 8680: # THIS INCLUDES REMOVING THE SPECIAL NODE POINTER STORED ! 8681: # IN ADDITION TO THE STANDARD TWO ENTRIES ON THE STACK. ! 8682: #page ! 8683: # ! 8684: # COMPOUNT PATTERN STRUCTURES (CONTINUED) ! 8685: # ! 8686: # FENCE (FUNCTION) ! 8687: # ---------------- ! 8688: # ! 8689: # +---+ THIS NODE (P$FNA) SAVES THE ! 8690: # I A I CURRENT HISTORY STACK AND A ! 8691: # +---+ POINTER TO NDFNB ON THE STACK. ! 8692: # I ! 8693: # I ! 8694: # +---+ THIS IS THE PATTERN STRUCTURE ! 8695: # I X I GIVEN AS THE ARGUMENT TO THE ! 8696: # +---+ FENCE FUNCTION. ! 8697: # I ! 8698: # I ! 8699: # +---+ THIS NODE P$FNC RESTORES THE OUTER ! 8700: # I C I HISTORY STACK PTR SAVED IN P$FNA, ! 8701: # +---+ AND STACKS THE INNER STACK BASE ! 8702: # PTR AND A POINTER TO NDFND ON THE ! 8703: # STACK. ! 8704: # ! 8705: # NDFNB (F$FNB) SIMPLY IS THE FAILURE EXIT FOR PATTERN ! 8706: # ARGUMENT FAILURE, AND IT POPS ITSELF AND FAILS ONTO THE ! 8707: # STACK. ! 8708: # ! 8709: # THE MATCH ROUTINE P$FNC ALLOWS FOR AN OPTIMIZATION WHEN ! 8710: # THE FENCE PATTERN LEAVES NO ALTERNATIVES. IN THIS CASE, ! 8711: # THE NDFNB ENTRY IS POPPED, AND THE MATCH CONTINUES. ! 8712: # ! 8713: # NDFND (P$FND) IS ENTERED WHEN THE PATTERN FAILS AFTER ! 8714: # GOING THROUGH A NON-OPTIMIZED P$FNC, AND IT POPS THE ! 8715: # STACK BACK PAST THE INNTER STACK BASE CREATED BY P$FNA ! 8716: #page ! 8717: # ! 8718: # COMPOUND PATTERNS (CONTINUED) ! 8719: # ! 8720: # EXPRESSION PATTERNS (RECURSIVE PATTERN MATCHES) ! 8721: # ----------------------------------------------- ! 8722: # ! 8723: # INITIAL ENTRY FOR A PATTERN NODE IS TO THE ROUTINE P$EXA. ! 8724: # IF THE EVALUATED RESULT OF THE EXPRESSION IS ITSELF A ! 8725: # PATTERN, THEN THE FOLLOWING STEPS ARE TAKEN TO ARRANGE ! 8726: # FOR PROPER RECURSIVE PROCESSING. ! 8727: # ! 8728: # 1) A POINTER TO THE CURRENT NODE (THE P$EXA NODE) IS ! 8729: # STORED ON THE HISTORY STACK WITH A DUMMY CURSOR. ! 8730: # ! 8731: # 2) A SPECIAL HISTORY STACK ENTRY IS MADE IN WHICH THE ! 8732: # NODE POINTER POINTS TO NDEXB, AND THE CURSOR VALUE ! 8733: # IS THE SAVED VALUE OF PMHBS ON ENTRY TO THIS NODE. ! 8734: # THE MATCH ROUTINE FOR NDEXB (P$EXB) RESTORES PMHBS ! 8735: # FROM THIS CURSOR ENTRY, POPS OFF THE P$EXA NODE ! 8736: # POINTER AND FAILS. ! 8737: # ! 8738: # 3) THE RESULTING HISTORY STACK POINTER IS SAVED IN ! 8739: # PMHBS TO ESTABLISH A NEW LEVEL OF HISTORY STACK. ! 8740: # ! 8741: # AFTER MATCHING A PATTERN, THE END OF MATCH ROUTINE GETS ! 8742: # CONTROL (P$NTH). THIS ROUTINE PROCEEDS AS FOLLOWS. ! 8743: # ! 8744: # 1) LOAD THE CURRENT VALUE OF PMHBS AND RECOGNIZE THE ! 8745: # OUTER LEVEL CASE BY THE FACT THAT THE ASSOCIATED ! 8746: # CURSOR IN THIS CASE IS THE PATTERN MATCH TYPE CODE ! 8747: # WHICH IS LESS THAN 3. TERMINATE THE MATCH IN THIS ! 8748: # CASE AND CONTINUE EXECUTION OF THE PROGRAM. ! 8749: # ! 8750: # 2) OTHERWISE MAKE A SPECIAL HISTORY STACK ENTRY IN ! 8751: # WHICH THE NODE POINTER POINTS TO THE SPECIAL NODE ! 8752: # NDEXC AND THE CURSOR IS THE CURRENT VALUE OF PMHBS. ! 8753: # THE MATCH ROUTINE FOR NDEXC (P$EXC) RESETS PMHBS TO ! 8754: # THIS (INNER) VALUE AND AND THEN FAILS. ! 8755: # ! 8756: # 3) USING THE HISTORY STACK ENTRY MADE ON STARTING THE ! 8757: # EXPRESSION (ACCESSIBLE WITH THE CURRENT VALUE OF ! 8758: # PMHBS), RESTORE THE P$EXA NODE POINTER AND THE OLD ! 8759: # PMHBS SETTING. TAKE THE SUCCESSOR AND CONTINUE. ! 8760: # ! 8761: # AN OPTIMIZATION IS POSSIBLE IF THE EXPRESSION PATTERN ! 8762: # MAKES NO ENTRIES ON THE HISTORY STACK. IN THIS CASE, ! 8763: # INSTEAD OF BUILDING THE P$EXC NODE IN STEP 2, IT IS MORE ! 8764: # EFFICIENT TO SIMPLY POP OFF THE P$EXB ENTRY AND ITS ! 8765: # ASSOCIATED NODE POINTER. THE EFFECT IS THE SAME. ! 8766: #page ! 8767: # ! 8768: # COMPOUND PATTERNS (CONTINUED) ! 8769: # ! 8770: # BINARY DOLLAR (IMMEDIATE ASSIGNMENT) ! 8771: # ------------------------------------ ! 8772: # ! 8773: # +---+ THIS NODE (P$IMA) STACKS THE CURSOR ! 8774: # I A I PMHBS AND A PTR TO NDIMB AND RESETS ! 8775: # +---+ THE STACK PTR PMHBS. ! 8776: # I ! 8777: # I ! 8778: # +---+ THIS IS THE LEFT STRUCTURE FOR THE ! 8779: # I X I PATTERN LEFT ARGUMENT OF THE ! 8780: # +---+ IMMEDIATE ASSIGNMENT CALL. ! 8781: # I ! 8782: # I ! 8783: # +---+ THIS NODE (P$IMC) PERFORMS THE ! 8784: # I C I----- ASSIGNMENT, POPS PMHBS AND STACKS ! 8785: # +---+ THE OLD PMHBS AND A PTR TO NDIMD. ! 8786: # ! 8787: # ! 8788: # THE STRUCTURE AND EXECUTION OF THIS PATTERN ARE SIMILAR ! 8789: # TO THOSE OF THE RECURSIVE EXPRESSION PATTERN MATCHING. ! 8790: # ! 8791: # THE MATCH ROUTINE FOR NDIMB (P$IMB) RESTORES THE OUTER ! 8792: # LEVEL VALUE OF PMHBS, UNSTACKS THE SAVED CURSOR AND FAILS ! 8793: # ! 8794: # THE MATCH ROUTINE P$IMC USES THE CURRENT VALUE OF PMHBS ! 8795: # TO LOCATE THE P$IMB ENTRY. THIS ENTRY IS USED TO MAKE ! 8796: # THE ASSIGNMENT AND RESTORE THE OUTER LEVEL VALUE OF ! 8797: # PMHBS. FINALLY, THE INNER LEVEL VALUE OF PMHBS AND A ! 8798: # POINTER TO THE SPECIAL NODE NDIMD ARE STACKED. ! 8799: # ! 8800: # THE MATCH ROUTINE FOR NDIMD (P$IMD) RESTORES THE INNER ! 8801: # LEVEL VALUE OF PMHBS AND FAILS BACK INTO THE STACK. ! 8802: # ! 8803: # AN OPTIMIZATION OCCURS IF THE INNER PATTERN MAKES NO ! 8804: # ENTRIES ON THE HISTORY STACK. IN THIS CASE, P$IMC POPS ! 8805: # THE P$IMB ENTRY INSTEAD OF MAKING A P$IMD ENTRY. ! 8806: #page ! 8807: # ! 8808: # ARBNO ! 8809: # ! 8810: # SEE COMPOUND PATTERNS SECTION FOR STUCTURE AND ! 8811: # ALGORITHM FOR MATCHING THIS NODE TYPE. ! 8812: # ! 8813: # NO PARAMETERS ! 8814: # ! 8815: .align 2 ! 8816: .word bl$p0 ! 8817: p$aba: # p0blk ! 8818: movl r7,-(sp) # stack cursor ! 8819: movl r9,-(sp) # stack dummy node ptr ! 8820: movl pmhbs,-(sp) # stack old stack base ptr ! 8821: movl $ndabb,-(sp) # stack ptr to node ndabb ! 8822: movl sp,pmhbs # store new stack base ptr ! 8823: jmp succp # succeed ! 8824: #page ! 8825: # ! 8826: # ARBNO (REMOVE P$ABA SPECIAL STACK ENTRY) ! 8827: # ! 8828: # NO PARAMETERS (DUMMY PATTERN) ! 8829: # ! 8830: p$abb: # entry point ! 8831: movl r7,pmhbs # restore history stack base ptr ! 8832: jmp flpop # fail and pop dummy node ptr ! 8833: #page ! 8834: # ! 8835: # ARBNO (CHECK IF ARG MATCHED NULL STRING) ! 8836: # ! 8837: # NO PARAMETERS (DUMMY PATTERN) ! 8838: # ! 8839: .align 2 ! 8840: .word bl$p0 ! 8841: p$abc: # p0blk ! 8842: movl pmhbs,r10 # keep p$abb stack base ! 8843: movl 4*3(r10),r6 # load initial cursor ! 8844: movl 4*1(r10),pmhbs # restore outer stack base ptr ! 8845: cmpl r10,sp # jump if no history stack entries ! 8846: beqlu pabc1 ! 8847: movl r10,-(sp) # else save inner pmhbs entry ! 8848: movl $ndabd,-(sp) # stack ptr to special node ndabd ! 8849: jmp pabc2 # merge ! 8850: # ! 8851: # OPTIMISE CASE OF NO EXTRA ENTRIES ON STACK FROM ARBNO ARG ! 8852: # ! 8853: pabc1: addl2 $4*num04,sp # remove ndabb entry and cursor ! 8854: # ! 8855: # MERGE TO CHECK FOR MATCHING OF NULL STRING ! 8856: # ! 8857: pabc2: cmpl r6,r7 # allow further attempt if non-null ! 8858: beqlu 0f ! 8859: jmp succp ! 8860: 0: ! 8861: movl 4*pthen(r9),r9 # bypass alternative node so as to .. ! 8862: jmp succp # ... refuse further match attempts ! 8863: #page ! 8864: # ! 8865: # ARBNO (TRY FOR ALTERNATIVES IN ARBNO ARGUMENT) ! 8866: # ! 8867: # NO PARAMETERS (DUMMY PATTERN) ! 8868: # ! 8869: p$abd: # entry point ! 8870: movl r7,pmhbs # restore inner stack base ptr ! 8871: jmp failp # and fail ! 8872: #page ! 8873: # ! 8874: # ABORT ! 8875: # ! 8876: # NO PARAMETERS ! 8877: # ! 8878: .align 2 ! 8879: .word bl$p0 ! 8880: p$abo: # p0blk ! 8881: jmp exfal # signal statement failure ! 8882: #page ! 8883: # ! 8884: # ALTERNATION ! 8885: # ! 8886: # PARM1 ALTERNATIVE NODE ! 8887: # ! 8888: .align 2 ! 8889: .word bl$p1 ! 8890: p$alt: # p1blk ! 8891: movl r7,-(sp) # stack cursor ! 8892: movl 4*parm1(r9),-(sp)# stack pointer to alternative ! 8893: jsb sbchk # check for stack overflow ! 8894: jmp succp # if all ok, then succeed ! 8895: #page ! 8896: # ! 8897: # ANY (ONE CHARACTER ARGUMENT) (1-CHAR STRING ALSO) ! 8898: # ! 8899: # PARM1 CHARACTER ARGUMENT ! 8900: # ! 8901: .align 2 ! 8902: .word bl$p1 ! 8903: p$ans: # p1blk ! 8904: cmpl r7,pmssl # fail if no chars left ! 8905: bnequ 0f ! 8906: jmp failp ! 8907: 0: ! 8908: movl r$pms,r10 # else point to subject string ! 8909: movab cfp$f(r10)[r7],r10 # point to current character ! 8910: movzbl (r10),r6 # load current character ! 8911: cmpl r6,4*parm1(r9) # fail if no match ! 8912: beqlu 0f ! 8913: jmp failp ! 8914: 0: ! 8915: incl r7 # else bump cursor ! 8916: jmp succp # and succeed ! 8917: #page ! 8918: # ! 8919: # ANY (MULTI-CHARACTER ARGUMENT CASE) ! 8920: # ! 8921: # PARM1 POINTER TO CTBLK ! 8922: # PARM2 BIT MASK TO SELECT BIT IN CTBLK ! 8923: # ! 8924: .align 2 ! 8925: .word bl$p2 ! 8926: p$any: # p2blk ! 8927: # ! 8928: # EXPRESSION ARGUMENT CASE MERGES HERE ! 8929: # ! 8930: pany1: cmpl r7,pmssl # fail if no characters left ! 8931: bnequ 0f ! 8932: jmp failp ! 8933: 0: ! 8934: movl r$pms,r10 # else point to subject string ! 8935: movab cfp$f(r10)[r7],r10 # get char ptr to current character ! 8936: movzbl (r10),r6 # load current character ! 8937: movl 4*parm1(r9),r10 # point to ctblk ! 8938: moval 0[r6],r6 # change to byte offset ! 8939: addl2 r6,r10 # point to entry in ctblk ! 8940: movl 4*ctchs(r10),r6 # load word from ctblk ! 8941: mcoml 4*parm2(r9),r11 # and with selected bit ! 8942: bicl2 r11,r6 ! 8943: tstl r6 # fail if no match ! 8944: bnequ 0f ! 8945: jmp failp ! 8946: 0: ! 8947: incl r7 # else bump cursor ! 8948: jmp succp # and succeed ! 8949: #page ! 8950: # ! 8951: # ANY (EXPRESSION ARGUMENT) ! 8952: # ! 8953: # PARM1 EXPRESSION POINTER ! 8954: # ! 8955: .align 2 ! 8956: .word bl$p1 ! 8957: p$ayd: # p1blk ! 8958: jsb evals # evaluate string argument ! 8959: .long er_043 # any evaluated argument is not string ! 8960: .long failp # fail if evaluation failure ! 8961: .long pany1 # merge multi-char case if ok ! 8962: #page ! 8963: # ! 8964: # P$ARB INITIAL ARB MATCH ! 8965: # ! 8966: # NO PARAMETERS ! 8967: # ! 8968: # THE P$ARB NODE IS PART OF A COMPOUND PATTERN STRUCTURE ! 8969: # FOR AN ARB PATTERN (SEE DESCRIPTION OF COMPOUND PATTERNS) ! 8970: # ! 8971: .align 2 ! 8972: .word bl$p0 ! 8973: p$arb: # p0blk ! 8974: movl 4*pthen(r9),r9 # load successor pointer ! 8975: movl r7,-(sp) # stack dummy cursor ! 8976: movl r9,-(sp) # stack successor pointer ! 8977: movl r7,-(sp) # stack cursor ! 8978: movl $ndarc,-(sp) # stack ptr to special node ndarc ! 8979: movl (r9),r11 # execute next node matching null ! 8980: jmp (r11) ! 8981: #page ! 8982: # ! 8983: # P$ARC EXTEND ARB MATCH ! 8984: # ! 8985: # NO PARAMETERS (DUMMY PATTERN) ! 8986: # ! 8987: p$arc: # entry point ! 8988: cmpl r7,pmssl # fail and pop stack to successor ! 8989: bnequ 0f ! 8990: jmp flpop ! 8991: 0: ! 8992: incl r7 # else bump cursor ! 8993: movl r7,-(sp) # stack updated cursor ! 8994: movl r9,-(sp) # restack pointer to ndarc node ! 8995: movl 4*2(sp),r9 # load successor pointer ! 8996: movl (r9),r11 # off to reexecute successor node ! 8997: jmp (r11) ! 8998: #page ! 8999: # ! 9000: # BAL ! 9001: # ! 9002: # NO PARAMETERS ! 9003: # ! 9004: # THE P$BAL NODE IS PART OF THE COMPOUND STRUCTURE BUILT ! 9005: # FOR BAL (SEE SECTION ON COMPOUND PATTERNS). ! 9006: # ! 9007: .align 2 ! 9008: .word bl$p0 ! 9009: p$bal: # p0blk ! 9010: clrl r8 # zero parentheses level counter ! 9011: movl r$pms,r10 # point to subject string ! 9012: movab cfp$f(r10)[r7],r10 # point to current character ! 9013: jmp pbal2 # jump into scan loop ! 9014: # ! 9015: # LOOP TO SCAN OUT CHARACTERS ! 9016: # ! 9017: pbal1: movzbl (r10)+,r6 # load next character, bump pointer ! 9018: incl r7 # push cursor for character ! 9019: cmpl r6,$ch$pp # jump if left paren ! 9020: beqlu pbal3 ! 9021: cmpl r6,$ch$rp # jump if right paren ! 9022: beqlu pbal4 ! 9023: tstl r8 # else succeed if at outer level ! 9024: beqlu pbal5 ! 9025: # ! 9026: # HERE AFTER PROCESSING ONE CHARACTER ! 9027: # ! 9028: pbal2: cmpl r7,pmssl # loop back unless end of string ! 9029: bnequ pbal1 ! 9030: jmp failp # in which case, fail ! 9031: # ! 9032: # HERE ON LEFT PAREN ! 9033: # ! 9034: pbal3: incl r8 # bump paren level ! 9035: jmp pbal2 # loop back to check end of string ! 9036: # ! 9037: # HERE FOR RIGHT PAREN ! 9038: # ! 9039: pbal4: tstl r8 # fail if no matching left paren ! 9040: bnequ 0f ! 9041: jmp failp ! 9042: 0: ! 9043: decl r8 # else decrement level counter ! 9044: tstl r8 # loop back if not at outer level ! 9045: bnequ pbal2 ! 9046: # ! 9047: # HERE AFTER SUCCESSFULLY SCANNING A BALANCED STRING ! 9048: # ! 9049: pbal5: movl r7,-(sp) # stack cursor ! 9050: movl r9,-(sp) # stack ptr to bal node for extend ! 9051: jmp succp # and succeed ! 9052: #page ! 9053: # ! 9054: # BREAK (EXPRESSION ARGUMENT) ! 9055: # ! 9056: # PARM1 EXPRESSION POINTER ! 9057: # ! 9058: .align 2 ! 9059: .word bl$p1 ! 9060: p$bkd: # p1blk ! 9061: jsb evals # evaluate string expression ! 9062: .long er_044 # break evaluated argument is not string ! 9063: .long failp # fail if evaluation fails ! 9064: .long pbrk1 # merge with multi-char case if ok ! 9065: #page ! 9066: # ! 9067: # BREAK (ONE CHARACTER ARGUMENT) ! 9068: # ! 9069: # PARM1 CHARACTER ARGUMENT ! 9070: # ! 9071: .align 2 ! 9072: .word bl$p1 ! 9073: p$bks: # p1blk ! 9074: movl pmssl,r8 # get subject string length ! 9075: subl2 r7,r8 # get number of characters left ! 9076: tstl r8 # fail if no characters left ! 9077: bnequ 0f ! 9078: jmp failp ! 9079: 0: ! 9080: # set counter for chars left ! 9081: movl r$pms,r10 # point to subject string ! 9082: movab cfp$f(r10)[r7],r10 # point to current character ! 9083: # ! 9084: # LOOP TO SCAN TILL BREAK CHARACTER FOUND ! 9085: # ! 9086: pbks1: movzbl (r10)+,r6 # load next char, bump pointer ! 9087: cmpl r6,4*parm1(r9) # succeed if break character found ! 9088: bnequ 0f ! 9089: jmp succp ! 9090: 0: ! 9091: incl r7 # else push cursor ! 9092: sobgtr r8,pbks1 # loop back if more to go ! 9093: jmp failp # fail if end of string, no break chr ! 9094: #page ! 9095: # ! 9096: # BREAK (MULTI-CHARACTER ARGUMENT) ! 9097: # ! 9098: # PARM1 POINTER TO CTBLK ! 9099: # PARM2 BIT MASK TO SELECT BIT COLUMN ! 9100: # ! 9101: .align 2 ! 9102: .word bl$p2 ! 9103: p$brk: # p2blk ! 9104: # ! 9105: # EXPRESSION ARGUMENT MERGES HERE ! 9106: # ! 9107: pbrk1: movl pmssl,r8 # load subject string length ! 9108: subl2 r7,r8 # get number of characters left ! 9109: tstl r8 # fail if no characters left ! 9110: bnequ 0f ! 9111: jmp failp ! 9112: 0: ! 9113: # set counter for characters left ! 9114: movl r$pms,r10 # else point to subject string ! 9115: movab cfp$f(r10)[r7],r10 # point to current character ! 9116: movl r9,psave # save node pointer ! 9117: # ! 9118: # LOOP TO SEARCH FOR BREAK CHARACTER ! 9119: # ! 9120: pbrk2: movzbl (r10)+,r6 # load next char, bump pointer ! 9121: movl 4*parm1(r9),r9 # load pointer to ctblk ! 9122: moval 0[r6],r6 # convert to byte offset ! 9123: addl2 r6,r9 # point to ctblk entry ! 9124: movl 4*ctchs(r9),r6 # load ctblk word ! 9125: movl psave,r9 # restore node pointer ! 9126: mcoml 4*parm2(r9),r11 # and with selected bit ! 9127: bicl2 r11,r6 ! 9128: tstl r6 # succeed if break character found ! 9129: beqlu 0f ! 9130: jmp succp ! 9131: 0: ! 9132: incl r7 # else push cursor ! 9133: sobgtr r8,pbrk2 # loop back unless end of string ! 9134: jmp failp # fail if end of string, no break chr ! 9135: #page ! 9136: # ! 9137: # BREAKX (EXTENSION) ! 9138: # ! 9139: # THIS IS THE ENTRY WHICH CAUSES AN EXTENSION OF A BREAKX ! 9140: # MATCH WHEN FAILURE OCCURS. SEE SECTION ON COMPOUND ! 9141: # PATTERNS FOR FULL DETAILS OF BREAKX MATCHING. ! 9142: # ! 9143: # NO PARAMETERS ! 9144: # ! 9145: .align 2 ! 9146: .word bl$p0 ! 9147: p$bkx: # p0blk ! 9148: incl r7 # step cursor past previous break chr ! 9149: jmp succp # succeed to rematch break ! 9150: #page ! 9151: # ! 9152: # BREAKX (EXPRESSION ARGUMENT) ! 9153: # ! 9154: # SEE SECTION ON COMPOUND PATTERNS FOR FULL STRUCTURE OF ! 9155: # BREAKX PATTERN. THE ACTUAL CHARACTER MATCHING USES A ! 9156: # BREAK NODE. HOWEVER, THE ENTRY FOR THE EXPRESSION ! 9157: # ARGUMENT CASE IS SEPARATED TO GET PROPER ERROR MESSAGES. ! 9158: # ! 9159: # PARM1 EXPRESSION POINTER ! 9160: # ! 9161: .align 2 ! 9162: .word bl$p1 ! 9163: p$bxd: # p1blk ! 9164: jsb evals # evaluate string argument ! 9165: .long er_045 # breakx evaluated argument is not string ! 9166: .long failp # fail if evaluation fails ! 9167: .long pbrk1 # merge with break if all ok ! 9168: #page ! 9169: # ! 9170: # CURSOR ASSIGNMENT ! 9171: # ! 9172: # PARM1 NAME BASE ! 9173: # PARM2 NAME OFFSET ! 9174: # ! 9175: .align 2 ! 9176: .word bl$p2 ! 9177: p$cas: # p2blk ! 9178: movl r9,-(sp) # save node pointer ! 9179: movl r7,-(sp) # save cursor ! 9180: movl 4*parm1(r9),r10 # load name base ! 9181: movl r7,r5 # load cursor as integer ! 9182: movl 4*parm2(r9),r7 # load name offset ! 9183: jsb icbld # get icblk for cursor value ! 9184: movl r7,r6 # move name offset ! 9185: movl r9,r7 # move value to assign ! 9186: jsb asinp # perform assignment ! 9187: .long flpop # fail on assignment failure ! 9188: movl (sp)+,r7 # else restore cursor ! 9189: movl (sp)+,r9 # restore node pointer ! 9190: jmp succp # and succeed matching null ! 9191: #page ! 9192: # ! 9193: # EXPRESSION NODE (P$EXA, INITIAL ENTRY) ! 9194: # ! 9195: # SEE COMPOUND PATTERNS DESCRIPTION FOR THE STRUCTURE AND ! 9196: # ALGORITHMS FOR HANDLING EXPRESSION NODES. ! 9197: # ! 9198: # PARM1 EXPRESSION POINTER ! 9199: # ! 9200: .align 2 ! 9201: .word bl$p1 ! 9202: p$exa: # p1blk ! 9203: jsb evalp # evaluate expression ! 9204: .long failp # fail if evaluation fails ! 9205: cmpl r6,$p$aaa # jump if result is not a pattern ! 9206: blequ pexa1 ! 9207: # ! 9208: # HERE IF RESULT OF EXPRESSION IS A PATTERN ! 9209: # ! 9210: movl r7,-(sp) # stack dummy cursor ! 9211: movl r9,-(sp) # stack ptr to p$exa node ! 9212: movl pmhbs,-(sp) # stack history stack base ptr ! 9213: movl $ndexb,-(sp) # stack ptr to special node ndexb ! 9214: movl sp,pmhbs # store new stack base pointer ! 9215: movl r10,r9 # copy node pointer ! 9216: movl (r9),r11 # match first node in expression pat ! 9217: jmp (r11) ! 9218: # ! 9219: # HERE IF RESULT OF EXPRESSION IS NOT A PATTERN ! 9220: # ! 9221: pexa1: cmpl r6,$b$scl # jump if it is already a string ! 9222: beqlu pexa2 ! 9223: movl r10,-(sp) # else stack result ! 9224: movl r9,r10 # save node pointer ! 9225: jsb gtstg # convert result to string ! 9226: .long er_046 # expression does not evaluate to pattern ! 9227: movl r9,r8 # copy string pointer ! 9228: movl r10,r9 # restore node pointer ! 9229: movl r8,r10 # copy string pointer again ! 9230: # ! 9231: # MERGE HERE WITH STRING POINTER IN XL ! 9232: # ! 9233: pexa2: tstl 4*sclen(r10) # just succeed if null string ! 9234: bnequ 0f ! 9235: jmp succp ! 9236: 0: ! 9237: jmp pstr1 # else merge with string circuit ! 9238: #page ! 9239: # ! 9240: # EXPRESSION NODE (P$EXB, REMOVE NDEXB ENTRY) ! 9241: # ! 9242: # SEE COMPOUND PATTERNS DESCRIPTION FOR THE STRUCTURE AND ! 9243: # ALGORITHMS FOR HANDLING EXPRESSION NODES. ! 9244: # ! 9245: # NO PARAMETERS (DUMMY PATTERN) ! 9246: # ! 9247: p$exb: # entry point ! 9248: movl r7,pmhbs # restore outer level stack pointer ! 9249: jmp flpop # fail and pop p$exa node ptr ! 9250: #page ! 9251: # ! 9252: # EXPRESSION NODE (P$EXC, REMOVE NDEXC ENTRY) ! 9253: # ! 9254: # SEE COMPOUND PATTERNS DESCRIPTION FOR THE STRUCTURE AND ! 9255: # ALGORITHMS FOR HANDLING EXPRESSION NODES. ! 9256: # ! 9257: # NO PARAMETERS (DUMMY PATTERN) ! 9258: # ! 9259: p$exc: # entry point ! 9260: movl r7,pmhbs # restore inner stack base pointer ! 9261: jmp failp # and fail into expr pattern alternvs ! 9262: #page ! 9263: # ! 9264: # FAIL ! 9265: # ! 9266: # NO PARAMETERS ! 9267: # ! 9268: .align 2 ! 9269: .word bl$p0 ! 9270: p$fal: # p0blk ! 9271: jmp failp # just signal failure ! 9272: #page ! 9273: # ! 9274: # FENCE ! 9275: # ! 9276: # SEE COMPOUND PATTERNS SECTION FOR THE STRUCTURE AND ! 9277: # ALGORITHM FOR MATCHING THIS NODE TYPE. ! 9278: # ! 9279: # NO PARAMETERS ! 9280: # ! 9281: .align 2 ! 9282: .word bl$p0 ! 9283: p$fen: # p0blk ! 9284: movl r7,-(sp) # stack dummy cursor ! 9285: movl $ndabo,-(sp) # stack ptr to abort node ! 9286: jmp succp # and succeed matching null ! 9287: #page ! 9288: # ! 9289: # FENCE (FUNCTION) ! 9290: # ! 9291: # SEE COMPOUND PATTERNS COMMENTS AT START OF THIS SECTION ! 9292: # FOR DETAILS OF SCHEME ! 9293: # ! 9294: # NO PARAMETERS ! 9295: # ! 9296: .align 2 ! 9297: .word bl$p0 ! 9298: p$fna: # p0blk ! 9299: movl pmhbs,-(sp) # stack current history stack base ! 9300: movl $ndfnb,-(sp) # stack indir ptr to p$fnb (failure) ! 9301: movl sp,pmhbs # begin new history stack ! 9302: jmp succp # succeed ! 9303: #page ! 9304: # ! 9305: # FENCE (FUNCTION) (RESET HISTORY STACK AND FAIL) ! 9306: # ! 9307: # NO PARAMETERS (DUMMY PATTERN) ! 9308: # ! 9309: .align 2 ! 9310: .word bl$p0 ! 9311: p$fnb: # p0blk ! 9312: movl r7,pmhbs # restore outer pmhbs stack base ! 9313: jmp failp # ...and fail ! 9314: #page ! 9315: # ! 9316: # FENCE (FUNCTION) (MAKE FENCE TRAP ENTRY ON STACK) ! 9317: # ! 9318: # NO PARAMETERS (DUMMY PATTERN) ! 9319: # ! 9320: .align 2 ! 9321: .word bl$p0 ! 9322: p$fnc: # p0blk ! 9323: movl pmhbs,r10 # get inner stack base ptr ! 9324: movl 4*num01(r10),pmhbs # restore outer stack base ! 9325: cmpl r10,sp # optimize if no alternatives ! 9326: beqlu pfnc1 ! 9327: movl r10,-(sp) # else stack inner stack base ! 9328: movl $ndfnd,-(sp) # stack ptr to ndfnd ! 9329: jmp succp # succeed ! 9330: # ! 9331: # HERE WHEN FENCE FUNCTION LEFT NOTHING ON THE STACK ! 9332: # ! 9333: pfnc1: addl2 $4*num02,sp # pop off p$fnb entry ! 9334: jmp succp # succeed ! 9335: #page ! 9336: # ! 9337: # FENCE (FUNCTION) (SKIP PAST ALTERNATIVES ON FAILURE) ! 9338: # ! 9339: # NO PARAMETERS (DUMMY PATTERN) ! 9340: # ! 9341: .align 2 ! 9342: .word bl$p0 ! 9343: p$fnd: # p0blk ! 9344: movl r7,sp # pop stack to fence() history base ! 9345: jmp flpop # pop base entry and fail ! 9346: #page ! 9347: # ! 9348: # IMMEDIATE ASSIGNMENT (INITIAL ENTRY, SAVE CURRENT CURSOR) ! 9349: # ! 9350: # SEE COMPOUND PATTERNS DESCRIPTION FOR DETAILS OF THE ! 9351: # STRUCTURE AND ALGORITHM FOR MATCHING THIS NODE TYPE. ! 9352: # ! 9353: # NO PARAMETERS ! 9354: # ! 9355: .align 2 ! 9356: .word bl$p0 ! 9357: p$ima: # p0blk ! 9358: movl r7,-(sp) # stack cursor ! 9359: movl r9,-(sp) # stack dummy node pointer ! 9360: movl pmhbs,-(sp) # stack old stack base pointer ! 9361: movl $ndimb,-(sp) # stack ptr to special node ndimb ! 9362: movl sp,pmhbs # store new stack base pointer ! 9363: jmp succp # and succeed ! 9364: #page ! 9365: # ! 9366: # IMMEDIATE ASSIGNMENT (REMOVE CURSOR MARK ENTRY) ! 9367: # ! 9368: # SEE COMPOUND PATTERNS DESCRIPTION FOR DETAILS OF THE ! 9369: # STRUCTURE AND ALGORITHMS FOR MATCHING THIS NODE TYPE. ! 9370: # ! 9371: # NO PARAMETERS (DUMMY PATTERN) ! 9372: # ! 9373: p$imb: # entry point ! 9374: movl r7,pmhbs # restore history stack base ptr ! 9375: jmp flpop # fail and pop dummy node ptr ! 9376: #page ! 9377: # ! 9378: # IMMEDIATE ASSIGNMENT (PERFORM ACTUAL ASSIGNMENT) ! 9379: # ! 9380: # SEE COMPOUND PATTERNS DESCRIPTION FOR DETAILS OF THE ! 9381: # STRUCTURE AND ALGORITHMS FOR MATCHING THIS NODE TYPE. ! 9382: # ! 9383: # PARM1 NAME BASE OF VARIABLE ! 9384: # PARM2 NAME OFFSET OF VARIABLE ! 9385: # ! 9386: .align 2 ! 9387: .word bl$p2 ! 9388: p$imc: # p2blk ! 9389: movl pmhbs,r10 # load pointer to p$imb entry ! 9390: movl r7,r6 # copy final cursor ! 9391: movl 4*3(r10),r7 # load initial cursor ! 9392: movl 4*1(r10),pmhbs # restore outer stack base pointer ! 9393: cmpl r10,sp # jump if no history stack entries ! 9394: beqlu pimc1 ! 9395: movl r10,-(sp) # else save inner pmhbs pointer ! 9396: movl $ndimd,-(sp) # and a ptr to special node ndimd ! 9397: jmp pimc2 # merge ! 9398: # ! 9399: # HERE IF NO ENTRIES MADE ON HISTORY STACK ! 9400: # ! 9401: pimc1: addl2 $4*num04,sp # remove ndimb entry and cursor ! 9402: # ! 9403: # MERGE HERE TO PERFORM ASSIGNMENT ! 9404: # ! 9405: pimc2: movl r6,-(sp) # save current (final) cursor ! 9406: movl r9,-(sp) # save current node pointer ! 9407: movl r$pms,r10 # point to subject string ! 9408: subl2 r7,r6 # compute substring length ! 9409: jsb sbstr # build substring ! 9410: movl r9,r7 # move result ! 9411: movl (sp),r9 # reload node pointer ! 9412: movl 4*parm1(r9),r10 # load name base ! 9413: movl 4*parm2(r9),r6 # load name offset ! 9414: jsb asinp # perform assignment ! 9415: .long flpop # fail if assignment fails ! 9416: movl (sp)+,r9 # else restore node pointer ! 9417: movl (sp)+,r7 # restore cursor ! 9418: jmp succp # and succeed ! 9419: #page ! 9420: # ! 9421: # IMMEDIATE ASSIGNMENT (REMOVE NDIMD ENTRY ON FAILURE) ! 9422: # ! 9423: # SEE COMPOUND PATTERNS DESCRIPTION FOR DETAILS OF THE ! 9424: # STRUCTURE AND ALGORITHMS FOR MATCHING THIS NODE TYPE. ! 9425: # ! 9426: # NO PARAMETERS (DUMMY PATTERN) ! 9427: # ! 9428: p$imd: # entry point ! 9429: movl r7,pmhbs # restore inner stack base pointer ! 9430: jmp failp # and fail ! 9431: #page ! 9432: # ! 9433: # LEN (INTEGER ARGUMENT) ! 9434: # ! 9435: # PARM1 INTEGER ARGUMENT ! 9436: # ! 9437: .align 2 ! 9438: .word bl$p1 ! 9439: p$len: # p1blk ! 9440: # ! 9441: # EXPRESSION ARGUMENT CASE MERGES HERE ! 9442: # ! 9443: plen1: addl2 4*parm1(r9),r7 # push cursor indicated amount ! 9444: cmpl r7,pmssl # succeed if not off end ! 9445: bgtru 0f ! 9446: jmp succp ! 9447: 0: ! 9448: jmp failp # else fail ! 9449: #page ! 9450: # ! 9451: # LEN (EXPRESSION ARGUMENT) ! 9452: # ! 9453: # PARM1 EXPRESSION POINTER ! 9454: # ! 9455: .align 2 ! 9456: .word bl$p1 ! 9457: p$lnd: # p1blk ! 9458: jsb evali # evaluate integer argument ! 9459: .long er_047 # len evaluated argument is not integer ! 9460: .long er_048 # len evaluated argument is negative or too large ! 9461: .long failp # fail if evaluation fails ! 9462: .long plen1 # merge with normal circuit if ok ! 9463: #page ! 9464: # ! 9465: # NOTANY (EXPRESSION ARGUMENT) ! 9466: # ! 9467: # PARM1 EXPRESSION POINTER ! 9468: # ! 9469: .align 2 ! 9470: .word bl$p1 ! 9471: p$nad: # p1blk ! 9472: jsb evals # evaluate string argument ! 9473: .long er_049 # notany evaluated argument is not string ! 9474: .long failp # fail if evaluation fails ! 9475: .long pnay1 # merge with multi-char case if ok ! 9476: #page ! 9477: # ! 9478: # NOTANY (ONE CHARACTER ARGUMENT) ! 9479: # ! 9480: # PARM1 CHARACTER ARGUMENT ! 9481: # ! 9482: .align 2 ! 9483: .word bl$p1 ! 9484: p$nas: # entry point ! 9485: cmpl r7,pmssl # fail if no chars left ! 9486: bnequ 0f ! 9487: jmp failp ! 9488: 0: ! 9489: movl r$pms,r10 # else point to subject string ! 9490: movab cfp$f(r10)[r7],r10 # point to current character in strin ! 9491: movzbl (r10),r6 # load current character ! 9492: cmpl r6,4*parm1(r9) # fail if match ! 9493: bnequ 0f ! 9494: jmp failp ! 9495: 0: ! 9496: incl r7 # else bump cursor ! 9497: jmp succp # and succeed ! 9498: #page ! 9499: # ! 9500: # NOTANY (MULTI-CHARACTER STRING ARGUMENT) ! 9501: # ! 9502: # PARM1 POINTER TO CTBLK ! 9503: # PARM2 BIT MASK TO SELECT BIT COLUMN ! 9504: # ! 9505: .align 2 ! 9506: .word bl$p2 ! 9507: p$nay: # p2blk ! 9508: # ! 9509: # EXPRESSION ARGUMENT CASE MERGES HERE ! 9510: # ! 9511: pnay1: cmpl r7,pmssl # fail if no characters left ! 9512: bnequ 0f ! 9513: jmp failp ! 9514: 0: ! 9515: movl r$pms,r10 # else point to subject string ! 9516: movab cfp$f(r10)[r7],r10 # point to current character ! 9517: movzbl (r10),r6 # load current character ! 9518: moval 0[r6],r6 # convert to byte offset ! 9519: movl 4*parm1(r9),r10 # load pointer to ctblk ! 9520: addl2 r6,r10 # point to entry in ctblk ! 9521: movl 4*ctchs(r10),r6 # load entry from ctblk ! 9522: mcoml 4*parm2(r9),r11 # and with selected bit ! 9523: bicl2 r11,r6 ! 9524: tstl r6 # fail if character is matched ! 9525: beqlu 0f ! 9526: jmp failp ! 9527: 0: ! 9528: incl r7 # else bump cursor ! 9529: jmp succp # and succeed ! 9530: #page ! 9531: # ! 9532: # END OF PATTERN MATCH ! 9533: # ! 9534: # THIS ROUTINE IS ENTERED ON SUCCESSFUL COMPLETION. ! 9535: # SEE DESCRIPTION OF EXPRESSION PATTERNS IN COMPOUND ! 9536: # PATTERN SECTION FOR HANDLING OF RECURSION IN MATCHING. ! 9537: # ! 9538: # NO PARAMETERS (DUMMY PATTERN) ! 9539: # ! 9540: p$nth: # entry point ! 9541: movl pmhbs,r10 # load pointer to base of stack ! 9542: movl 4*1(r10),r6 # load saved pmhbs (or pattern type) ! 9543: cmpl r6,$num02 # jump if outer level (pattern type) ! 9544: blequ pnth2 ! 9545: # ! 9546: # HERE WE ARE AT THE END OF MATCHING AN EXPRESSION PATTERN ! 9547: # ! 9548: movl r6,pmhbs # restore outer stack base pointer ! 9549: movl 4*2(r10),r9 # restore pointer to p$exa node ! 9550: cmpl r10,sp # jump if no history stack entries ! 9551: beqlu pnth1 ! 9552: movl r10,-(sp) # else stack inner stack base ptr ! 9553: movl $ndexc,-(sp) # stack ptr to special node ndexc ! 9554: jmp succp # and succeed ! 9555: # ! 9556: # HERE IF NO HISTORY STACK ENTRIES DURING PATTERN ! 9557: # ! 9558: pnth1: addl2 $4*num04,sp # remove p$exb entry and node ptr ! 9559: jmp succp # and succeed ! 9560: # ! 9561: # HERE IF END OF MATCH AT OUTER LEVEL ! 9562: # ! 9563: pnth2: movl r7,pmssl # save final cursor in safe place ! 9564: tstl pmdfl # jump if no pattern assignments ! 9565: beqlu pnth6 ! 9566: #page ! 9567: # ! 9568: # END OF PATTERN MATCH (CONTINUED) ! 9569: # ! 9570: # NOW WE MUST PERFORM PATTERN ASSIGNMENTS. THIS IS DONE BY ! 9571: # SCANNING THE HISTORY STACK FOR MATCHING NDPAB-NDPAD PAIRS ! 9572: # ! 9573: pnth3: subl2 $4,r10 # point past cursor entry ! 9574: movl -(r10),r6 # load node pointer ! 9575: cmpl r6,$ndpad # jump if ndpad entry ! 9576: beqlu pnth4 ! 9577: cmpl r6,$ndpab # jump if not ndpab entry ! 9578: bnequ pnth5 ! 9579: # ! 9580: # HERE FOR NDPAB ENTRY, STACK INITIAL CURSOR ! 9581: # NOTE THAT THERE MUST BE MORE ENTRIES ON THE STACK. ! 9582: # ! 9583: movl 4*1(r10),-(sp) # stack initial cursor ! 9584: jsb sbchk # check for stack overflow ! 9585: jmp pnth3 # loop back if ok ! 9586: # ! 9587: # HERE FOR NDPAD ENTRY. THE STARTING CURSOR FROM THE ! 9588: # MATCHING NDPAD ENTRY IS NOW THE TOP STACK ENTRY. ! 9589: # ! 9590: pnth4: movl 4*1(r10),r6 # load final cursor ! 9591: movl (sp),r7 # load initial cursor from stack ! 9592: movl r10,(sp) # save history stack scan ptr ! 9593: subl2 r7,r6 # compute length of string ! 9594: # ! 9595: # BUILD SUBSTRING AND PERFORM ASSIGNMENT ! 9596: # ! 9597: movl r$pms,r10 # point to subject string ! 9598: jsb sbstr # construct substring ! 9599: movl r9,r7 # copy substring pointer ! 9600: movl (sp),r10 # reload history stack scan ptr ! 9601: movl 4*2(r10),r10 # load pointer to p$pac node with nam ! 9602: movl 4*parm2(r10),r6 # load name offset ! 9603: movl 4*parm1(r10),r10# load name base ! 9604: jsb asinp # perform assignment ! 9605: .long exfal # match fails if name eval fails ! 9606: movl (sp)+,r10 # else restore history stack ptr ! 9607: #page ! 9608: # ! 9609: # END OF PATTERN MATCH (CONTINUED) ! 9610: # ! 9611: # HERE CHECK FOR END OF ENTRIES ! 9612: # ! 9613: pnth5: cmpl r10,sp # loop if more entries to scan ! 9614: bnequ pnth3 ! 9615: # ! 9616: # HERE AFTER DEALING WITH PATTERN ASSIGNMENTS ! 9617: # ! 9618: pnth6: movl pmhbs,sp # wipe out history stack ! 9619: movl (sp)+,r7 # load initial cursor ! 9620: movl (sp)+,r8 # load match type code ! 9621: movl pmssl,r6 # load final cursor value ! 9622: movl r$pms,r10 # point to subject string ! 9623: clrl r$pms # clear subject string ptr for gbcol ! 9624: tstl r8 # jump if call by name ! 9625: beqlu pnth7 ! 9626: cmpl r8,$num02 # exit if statement level call ! 9627: bnequ 0f ! 9628: jmp exits ! 9629: 0: ! 9630: # ! 9631: # HERE WE HAVE A CALL BY VALUE, BUILD SUBSTRING ! 9632: # ! 9633: subl2 r7,r6 # compute length of string ! 9634: jsb sbstr # build substring ! 9635: jmp exixr # and exit with substring value ! 9636: # ! 9637: # HERE FOR CALL BY NAME, MAKE STACK ENTRIES FOR O$RPL ! 9638: # ! 9639: pnth7: movl r7,-(sp) # stack initial cursor ! 9640: movl r6,-(sp) # stack final cursor ! 9641: tstl r$pmb # skip if subject not buffer ! 9642: beqlu pnth8 ! 9643: movl r$pmb,r10 # else get ptr to bcblk instead ! 9644: # ! 9645: # HERE WITH XL POINTING TO SCBLK OR BCBLK ! 9646: # ! 9647: pnth8: movl r10,-(sp) # stack subject pointer ! 9648: jmp exits # exit with special entry on stack ! 9649: #page ! 9650: # ! 9651: # POS (INTEGER ARGUMENT) ! 9652: # ! 9653: # PARM1 INTEGER ARGUMENT ! 9654: # ! 9655: .align 2 ! 9656: .word bl$p1 ! 9657: p$pos: # p1blk ! 9658: # ! 9659: # EXPRESSION ARGUMENT CASE MERGES HERE ! 9660: # ! 9661: ppos1: cmpl r7,4*parm1(r9) # succeed if at right location ! 9662: bnequ 0f ! 9663: jmp succp ! 9664: 0: ! 9665: jmp failp # else fail ! 9666: #page ! 9667: # ! 9668: # POS (EXPRESSION ARGUMENT) ! 9669: # ! 9670: # PARM1 EXPRESSION POINTER ! 9671: # ! 9672: .align 2 ! 9673: .word bl$p1 ! 9674: p$psd: # p1blk ! 9675: jsb evali # evaluate integer argument ! 9676: .long er_050 # pos evaluated argument is not integer ! 9677: .long er_051 # pos evaluated argument is negative or too large ! 9678: .long failp # fail if evaluation fails ! 9679: .long ppos1 # merge with normal case if ok ! 9680: #page ! 9681: # ! 9682: # PATTERN ASSIGNMENT (INITIAL ENTRY, SAVE CURSOR) ! 9683: # ! 9684: # SEE COMPOUND PATTERNS DESCRIPTION FOR THE STRUCTURE AND ! 9685: # ALGORITHMS FOR MATCHING THIS NODE TYPE. ! 9686: # ! 9687: # NO PARAMETERS ! 9688: # ! 9689: .align 2 ! 9690: .word bl$p0 ! 9691: p$paa: # p0blk ! 9692: movl r7,-(sp) # stack initial cursor ! 9693: movl $ndpab,-(sp) # stack ptr to ndpab special node ! 9694: jmp succp # and succeed matching null ! 9695: #page ! 9696: # ! 9697: # PATTERN ASSIGNMENT (REMOVE SAVED CURSOR) ! 9698: # ! 9699: # SEE COMPOUND PATTERNS DESCRIPTION FOR THE STRUCTURE AND ! 9700: # ALGORITHMS FOR MATCHING THIS NODE TYPE. ! 9701: # ! 9702: # NO PARAMETERS (DUMMY PATTERN) ! 9703: # ! 9704: p$pab: # entry point ! 9705: jmp failp # just fail (entry is already popped) ! 9706: #page ! 9707: # ! 9708: # PATTERN ASSIGNMENT (END OF MATCH, MAKE ASSIGN ENTRY) ! 9709: # ! 9710: # SEE COMPOUND PATTERNS DESCRIPTION FOR THE STRUCTURE AND ! 9711: # ALGORITHMS FOR MATCHING THIS NODE TYPE. ! 9712: # ! 9713: # PARM1 NAME BASE OF VARIABLE ! 9714: # PARM2 NAME OFFSET OF VARIABLE ! 9715: # ! 9716: .align 2 ! 9717: .word bl$p2 ! 9718: p$pac: # p2blk ! 9719: movl r7,-(sp) # stack dummy cursor value ! 9720: movl r9,-(sp) # stack pointer to p$pac node ! 9721: movl r7,-(sp) # stack final cursor ! 9722: movl $ndpad,-(sp) # stack ptr to special ndpad node ! 9723: movl sp,pmdfl # set dot flag non-zero ! 9724: jmp succp # and succeed ! 9725: #page ! 9726: # ! 9727: # PATTERN ASSIGNMENT (REMOVE ASSIGN ENTRY) ! 9728: # ! 9729: # SEE COMPOUND PATTERNS DESCRIPTION FOR THE STRUCTURE AND ! 9730: # ALGORITHMS FOR MATCHING THIS NODE TYPE. ! 9731: # ! 9732: # NO PARAMETERS (DUMMY NODE) ! 9733: # ! 9734: p$pad: # entry point ! 9735: jmp flpop # fail and remove p$pac node ! 9736: #page ! 9737: # ! 9738: # REM ! 9739: # ! 9740: # NO PARAMETERS ! 9741: # ! 9742: .align 2 ! 9743: .word bl$p0 ! 9744: p$rem: # p0blk ! 9745: movl pmssl,r7 # point cursor to end of string ! 9746: jmp succp # and succeed ! 9747: #page ! 9748: # ! 9749: # RPOS (EXPRESSION ARGUMENT) ! 9750: # ! 9751: # PARM1 EXPRESSION POINTER ! 9752: # ! 9753: .align 2 ! 9754: .word bl$p1 ! 9755: p$rpd: # p1blk ! 9756: jsb evali # evaluate integer argument ! 9757: .long er_052 # rpos evaluated argument is not integer ! 9758: .long er_053 # rpos evaluated argument is negative or too large ! 9759: .long failp # fail if evaluation fails ! 9760: .long prps1 # merge with normal case if ok ! 9761: #page ! 9762: # ! 9763: # RPOS (INTEGER ARGUMENT) ! 9764: # ! 9765: # PARM1 INTEGER ARGUMENT ! 9766: # ! 9767: .align 2 ! 9768: .word bl$p1 ! 9769: p$rps: # p1blk ! 9770: # ! 9771: # EXPRESSION ARGUMENT CASE MERGES HERE ! 9772: # ! 9773: prps1: movl pmssl,r8 # get length of string ! 9774: subl2 r7,r8 # get number of characters remaining ! 9775: cmpl r8,4*parm1(r9) # succeed if at right location ! 9776: bnequ 0f ! 9777: jmp succp ! 9778: 0: ! 9779: jmp failp # else fail ! 9780: #page ! 9781: # ! 9782: # RTAB (INTEGER ARGUMENT) ! 9783: # ! 9784: # PARM1 INTEGER ARGUMENT ! 9785: # ! 9786: .align 2 ! 9787: .word bl$p1 ! 9788: p$rtb: # p1blk ! 9789: # ! 9790: # EXPRESSION ARGUMENT CASE MERGES HERE ! 9791: # ! 9792: prtb1: movl r7,r8 # save initial cursor ! 9793: movl pmssl,r7 # point to end of string ! 9794: cmpl r7,4*parm1(r9) # fail if string not long enough ! 9795: bgequ 0f ! 9796: jmp failp ! 9797: 0: ! 9798: subl2 4*parm1(r9),r7 # else set new cursor ! 9799: cmpl r7,r8 # and succeed if not too far already ! 9800: blssu 0f ! 9801: jmp succp ! 9802: 0: ! 9803: jmp failp # in which case, fail ! 9804: #page ! 9805: # ! 9806: # RTAB (EXPRESSION ARGUMENT) ! 9807: # ! 9808: # PARM1 EXPRESSION POINTER ! 9809: # ! 9810: .align 2 ! 9811: .word bl$p1 ! 9812: p$rtd: # p1blk ! 9813: jsb evali # evaluate integer argument ! 9814: .long er_054 # rtab evaluated argument is not integer ! 9815: .long er_055 # rtab evaluated argument is negative or too large ! 9816: .long failp # fail if evaluation fails ! 9817: .long prtb1 # merge with normal case if success ! 9818: #page ! 9819: # ! 9820: # SPAN (EXPRESSION ARGUMENT) ! 9821: # ! 9822: # PARM1 EXPRESSION POINTER ! 9823: # ! 9824: .align 2 ! 9825: .word bl$p1 ! 9826: p$spd: # p1blk ! 9827: jsb evals # evaluate string argument ! 9828: .long er_056 # span evaluated argument is not string ! 9829: .long failp # fail if evaluation fails ! 9830: .long pspn1 # merge with multi-char case if ok ! 9831: #page ! 9832: # ! 9833: # SPAN (MULTI-CHARACTER ARGUMENT CASE) ! 9834: # ! 9835: # PARM1 POINTER TO CTBLK ! 9836: # PARM2 BIT MASK TO SELECT BIT COLUMN ! 9837: # ! 9838: .align 2 ! 9839: .word bl$p2 ! 9840: p$spn: # p2blk ! 9841: # ! 9842: # EXPRESSION ARGUMENT CASE MERGES HERE ! 9843: # ! 9844: pspn1: movl pmssl,r8 # copy subject string length ! 9845: subl2 r7,r8 # calculate number of characters left ! 9846: tstl r8 # fail if no characters left ! 9847: bnequ 0f ! 9848: jmp failp ! 9849: 0: ! 9850: movl r$pms,r10 # point to subject string ! 9851: movab cfp$f(r10)[r7],r10 # point to current character ! 9852: movl r7,psavc # save initial cursor ! 9853: movl r9,psave # save node pointer ! 9854: # set counter for chars left ! 9855: # ! 9856: # LOOP TO SCAN MATCHING CHARACTERS ! 9857: # ! 9858: pspn2: movzbl (r10)+,r6 # load next character, bump pointer ! 9859: moval 0[r6],r6 # convert to byte offset ! 9860: movl 4*parm1(r9),r9 # point to ctblk ! 9861: addl2 r6,r9 # point to ctblk entry ! 9862: movl 4*ctchs(r9),r6 # load ctblk entry ! 9863: movl psave,r9 # restore node pointer ! 9864: mcoml 4*parm2(r9),r11 # and with selected bit ! 9865: bicl2 r11,r6 ! 9866: tstl r6 # jump if no match ! 9867: beqlu pspn3 ! 9868: incl r7 # else push cursor ! 9869: sobgtr r8,pspn2 # loop back unless end of string ! 9870: # ! 9871: # HERE AFTER SCANNING MATCHING CHARACTERS ! 9872: # ! 9873: pspn3: cmpl r7,psavc # succeed if chars matched ! 9874: beqlu 0f ! 9875: jmp succp ! 9876: 0: ! 9877: jmp failp # else fail if null string matched ! 9878: #page ! 9879: # ! 9880: # SPAN (ONE CHARACTER ARGUMENT) ! 9881: # ! 9882: # PARM1 CHARACTER ARGUMENT ! 9883: # ! 9884: .align 2 ! 9885: .word bl$p1 ! 9886: p$sps: # p1blk ! 9887: movl pmssl,r8 # get subject string length ! 9888: subl2 r7,r8 # calculate number of characters left ! 9889: tstl r8 # fail if no characters left ! 9890: bnequ 0f ! 9891: jmp failp ! 9892: 0: ! 9893: movl r$pms,r10 # else point to subject string ! 9894: movab cfp$f(r10)[r7],r10 # point to current character ! 9895: movl r7,psavc # save initial cursor ! 9896: # set counter for characters left ! 9897: # ! 9898: # LOOP TO SCAN MATCHING CHARACTERS ! 9899: # ! 9900: psps1: movzbl (r10)+,r6 # load next character, bump pointer ! 9901: cmpl r6,4*parm1(r9) # jump if no match ! 9902: bnequ psps2 ! 9903: incl r7 # else push cursor ! 9904: sobgtr r8,psps1 # and loop unless end of string ! 9905: # ! 9906: # HERE AFTER SCANNING MATCHING CHARACTERS ! 9907: # ! 9908: psps2: cmpl r7,psavc # succeed if chars matched ! 9909: beqlu 0f ! 9910: jmp succp ! 9911: 0: ! 9912: jmp failp # fail if null string matched ! 9913: #page ! 9914: # ! 9915: # MULTI-CHARACTER STRING ! 9916: # ! 9917: # NOTE THAT ONE CHARACTER STRINGS USE THE CIRCUIT FOR ! 9918: # ONE CHARACTER ANY ARGUMENTS (P$AN1). ! 9919: # ! 9920: # PARM1 POINTER TO SCBLK FOR STRING ARG ! 9921: # ! 9922: .align 2 ! 9923: .word bl$p1 ! 9924: p$str: # p1blk ! 9925: movl 4*parm1(r9),r10 # get pointer to string ! 9926: # ! 9927: # MERGE HERE AFTER EVALUATING EXPRESSION WITH STRING VALUE ! 9928: # ! 9929: pstr1: movl r9,psave # save node pointer ! 9930: movl r$pms,r9 # load subject string pointer ! 9931: movab cfp$f(r9)[r7],r9# point to current character ! 9932: addl2 4*sclen(r10),r7 # compute new cursor position ! 9933: cmpl r7,pmssl # fail if past end of string ! 9934: blequ 0f ! 9935: jmp failp ! 9936: 0: ! 9937: movl r7,psavc # save updated cursor ! 9938: movl 4*sclen(r10),r6 # get number of chars to compare ! 9939: movab cfp$f(r10),r10 # point to chars of test string ! 9940: jsb sbcmc # compare, fail if not equal ! 9941: .long failp ! 9942: .long failp ! 9943: movl psave,r9 # if all matched, restore node ptr ! 9944: movl psavc,r7 # restore updated cursor ! 9945: jmp succp # and succeed ! 9946: #page ! 9947: # ! 9948: # SUCCEED ! 9949: # ! 9950: # SEE SECTION ON COMPOUND PATTERNS FOR DETAILS OF THE ! 9951: # STRUCTURE AND ALGORITHMS FOR MATCHING THIS NODE TYPE ! 9952: # ! 9953: # NO PARAMETERS ! 9954: # ! 9955: .align 2 ! 9956: .word bl$p0 ! 9957: p$suc: # p0blk ! 9958: movl r7,-(sp) # stack cursor ! 9959: movl r9,-(sp) # stack pointer to this node ! 9960: jmp succp # succeed matching null ! 9961: #page ! 9962: # ! 9963: # TAB (INTEGER ARGUMENT) ! 9964: # ! 9965: # PARM1 INTEGER ARGUMENT ! 9966: # ! 9967: .align 2 ! 9968: .word bl$p1 ! 9969: p$tab: # p1blk ! 9970: # ! 9971: # EXPRESSION ARGUMENT CASE MERGES HERE ! 9972: # ! 9973: ptab1: cmpl r7,4*parm1(r9) # fail if too far already ! 9974: blequ 0f ! 9975: jmp failp ! 9976: 0: ! 9977: movl 4*parm1(r9),r7 # else set new cursor position ! 9978: cmpl r7,pmssl # succeed if not off end ! 9979: bgtru 0f ! 9980: jmp succp ! 9981: 0: ! 9982: jmp failp # else fail ! 9983: #page ! 9984: # ! 9985: # TAB (EXPRESSION ARGUMENT) ! 9986: # ! 9987: # PARM1 EXPRESSION POINTER ! 9988: # ! 9989: .align 2 ! 9990: .word bl$p1 ! 9991: p$tbd: # p1blk ! 9992: jsb evali # evaluate integer argument ! 9993: .long er_057 # tab evaluated argument is not integer ! 9994: .long er_058 # tab evaluated argument is negative or too large ! 9995: .long failp # fail if evaluation fails ! 9996: .long ptab1 # merge with normal case if ok ! 9997: #page ! 9998: # ! 9999: # ANCHOR MOVEMENT ! 10000: # ! 10001: # NO PARAMETERS (DUMMY NODE) ! 10002: # ! 10003: p$una: # entry point ! 10004: movl r7,r9 # copy initial pattern node pointer ! 10005: movl (sp),r7 # get initial cursor ! 10006: cmpl r7,pmssl # match fails if at end of string ! 10007: bnequ 0f ! 10008: jmp exfal ! 10009: 0: ! 10010: incl r7 # else increment cursor ! 10011: movl r7,(sp) # store incremented cursor ! 10012: movl r9,-(sp) # restack initial node ptr ! 10013: movl $nduna,-(sp) # restack unanchored node ! 10014: movl (r9),r11 # rematch first node ! 10015: jmp (r11) ! 10016: #page ! 10017: # ! 10018: # END OF PATTERN MATCH ROUTINES ! 10019: # ! 10020: # THE FOLLOWING ENTRY POINT MARKS THE END OF THE PATTERN ! 10021: # MATCHING ROUTINES AND ALSO THE END OF THE ENTRY POINTS ! 10022: # REFERENCED FROM THE FIRST WORD OF BLOCKS IN DYNAMIC STORE ! 10023: # ! 10024: .align 2 ! 10025: .word bl$$i ! 10026: p$yyy: # mark last entry in pattern section ! 10027: #title s p i t b o l -- predefined snobol4 functions ! 10028: # ! 10029: # THE FOLLOWING SECTION CONTAINS CODING FOR FUNCTIONS ! 10030: # WHICH ARE PREDEFINED AND AVAILABLE AT THE SNOBOL LEVEL. ! 10031: # ! 10032: # THESE ROUTINES RECEIVE CONTROL DIRECTLY FROM THE CODE OR ! 10033: # INDIRECTLY THROUGH THE O$FNC, O$FNS OR CFUNC ROUTINES. ! 10034: # IN BOTH CASES THE CONDITIONS ON ENTRY ARE AS FOLLOWS ! 10035: # ! 10036: # THE ARGUMENTS ARE ON THE STACK. THE NUMBER OF ARGUMENTS ! 10037: # HAS BEEN ADJUSTED TO CORRESPOND TO THE SVBLK SVNAR FIELD. ! 10038: # ! 10039: # IN CERTAIN FUNCTIONS THE DIRECT CALL IS NOT PERMITTED ! 10040: # AND IN THESE INSTANCES WE ALSO HAVE. ! 10041: # ! 10042: # (WA) ACTUAL NUMBER OF ARGUMENTS IN CALL ! 10043: # ! 10044: # CONTROL RETURNS BY PLACING THE FUNCTION RESULT VALUE ON ! 10045: # ON THE STACK AND CONTINUING EXECUTION WITH THE NEXT ! 10046: # WORD FROM THE GENERATED CODE. ! 10047: # ! 10048: # THE NAMES OF THE ENTRY POINTS OF THESE FUNCTIONS ARE OF ! 10049: # THE FORM S$XXX WHERE XXX IS THE THREE LETTER CODE FOR ! 10050: # THE SYSTEM VARIABLE NAME. THE FUNCTIONS ARE IN ORDER ! 10051: # ALPHABETICALLY BY THEIR ENTRY NAMES. ! 10052: #page ! 10053: # ! 10054: # ANY ! 10055: # ! 10056: s$any: # entry point ! 10057: movl $p$ans,r7 # set pcode for single char case ! 10058: movl $p$any,r10 # pcode for multi-char case ! 10059: movl $p$ayd,r8 # pcode for expression case ! 10060: jsb patst # call common routine to build node ! 10061: .long er_059 # any argument is not string or expression ! 10062: jmp exixr # jump for next code word ! 10063: #page ! 10064: # ! 10065: # APPEND ! 10066: # ! 10067: s$apn: # entry point ! 10068: movl (sp)+,r10 # get append argument ! 10069: movl (sp)+,r9 # get bcblk ! 10070: cmpl (r9),$b$bct # ok if first arg is bcblk ! 10071: beqlu sapn1 ! 10072: jmp er_275 # append first argument is not buffer ! 10073: # ! 10074: # HERE TO DO THE APPEND ! 10075: # ! 10076: sapn1: jsb apndb # do the append ! 10077: .long er_276 # append second argument is not string ! 10078: .long exfal # no room - fail ! 10079: jmp exnul # exit with null result ! 10080: #page ! 10081: # ! 10082: # APPLY ! 10083: # ! 10084: # APPLY DOES NOT PERMIT THE DIRECT (FAST) CALL SO THAT ! 10085: # WA CONTAINS THE ACTUAL NUMBER OF ARGUMENTS PASSED. ! 10086: # ! 10087: s$app: # entry point ! 10088: tstl r6 # jump if no arguments ! 10089: beqlu sapp3 ! 10090: decl r6 # else get applied func arg count ! 10091: movl r6,r7 # copy ! 10092: moval 0[r7],r7 # convert to bytes ! 10093: movl sp,r10 # copy stack pointer ! 10094: addl2 r7,r10 # point to function argument on stack ! 10095: movl (r10),r9 # load function ptr (apply 1st arg) ! 10096: tstl r6 # jump if no args for applied func ! 10097: beqlu sapp2 ! 10098: movl r6,r7 # else set counter for loop ! 10099: # ! 10100: # LOOP TO MOVE ARGUMENTS UP ON STACK ! 10101: # ! 10102: sapp1: subl2 $4,r10 # point to next argument ! 10103: movl (r10),4*1(r10) # move argument up ! 10104: sobgtr r7,sapp1 # loop till all moved ! 10105: # ! 10106: # MERGE HERE TO CALL FUNCTION (WA = NUMBER OF ARGUMENTS) ! 10107: # ! 10108: sapp2: addl2 $4,sp # adjust stack ptr for apply 1st arg ! 10109: jsb gtnvr # get variable block addr for func ! 10110: .long sapp3 # jump if not natural variable ! 10111: movl 4*vrfnc(r9),r10 # else point to function block ! 10112: jmp cfunc # go call applied function ! 10113: # ! 10114: # HERE FOR INVALID FIRST ARGUMENT ! 10115: # ! 10116: sapp3: jmp er_060 # apply first arg is not natural variable name ! 10117: #page ! 10118: # ! 10119: # ARBNO ! 10120: # ! 10121: # ARBNO BUILDS A COMPOUND PATTERN. SEE DESCRIPTION AT ! 10122: # START OF PATTERN MATCHING SECTION FOR STRUCTURE FORMED. ! 10123: # ! 10124: s$abn: # entry point ! 10125: clrl r9 # set parm1 = 0 for the moment ! 10126: movl $p$alt,r7 # set pcode for alternative node ! 10127: jsb pbild # build alternative node ! 10128: movl r9,r10 # save ptr to alternative pattern ! 10129: movl $p$abc,r7 # pcode for p$abc ! 10130: clrl r9 # p0blk ! 10131: jsb pbild # build p$abc node ! 10132: movl r10,4*pthen(r9) # put alternative node as successor ! 10133: movl r10,r6 # remember alternative node pointer ! 10134: movl r9,r10 # copy p$abc node ptr ! 10135: movl (sp),r9 # load arbno argument ! 10136: movl r6,(sp) # stack alternative node pointer ! 10137: jsb gtpat # get arbno argument as pattern ! 10138: .long er_061 # arbno argument is not pattern ! 10139: jsb pconc # concat arg with p$abc node ! 10140: movl r9,r10 # remember ptr to concd patterns ! 10141: movl $p$aba,r7 # pcode for p$aba ! 10142: clrl r9 # p0blk ! 10143: jsb pbild # build p$aba node ! 10144: movl r10,4*pthen(r9) # concatenate nodes ! 10145: movl (sp),r10 # recall ptr to alternative node ! 10146: movl r9,4*parm1(r10) # point alternative back to argument ! 10147: jmp exits # jump for next code word ! 10148: #page ! 10149: # ! 10150: # ARG ! 10151: # ! 10152: s$arg: # entry point ! 10153: jsb gtsmi # get second arg as small integer ! 10154: .long er_062 # arg second argument is not integer ! 10155: .long exfal # fail if out of range or negative ! 10156: movl r9,r6 # save argument number ! 10157: movl (sp)+,r9 # load first argument ! 10158: jsb gtnvr # locate vrblk ! 10159: .long sarg1 # jump if not natural variable ! 10160: movl 4*vrfnc(r9),r9 # else load function block pointer ! 10161: cmpl (r9),$b$pfc # jump if not program defined ! 10162: bnequ sarg1 ! 10163: tstl r6 # fail if arg number is zero ! 10164: bnequ 0f ! 10165: jmp exfal ! 10166: 0: ! 10167: cmpl r6,4*fargs(r9) # fail if arg number is too large ! 10168: blequ 0f ! 10169: jmp exfal ! 10170: 0: ! 10171: moval 0[r6],r6 # else convert to byte offset ! 10172: addl2 r6,r9 # point to argument selected ! 10173: movl 4*pfagb(r9),r9 # load argument vrblk pointer ! 10174: jmp exvnm # exit to build nmblk ! 10175: # ! 10176: # HERE IF 1ST ARGUMENT IS BAD ! 10177: # ! 10178: sarg1: jmp er_063 # arg first argument is not program function name ! 10179: #page ! 10180: # ! 10181: # ARRAY ! 10182: # ! 10183: s$arr: # entry point ! 10184: movl (sp)+,r10 # load initial element value ! 10185: movl (sp)+,r9 # load first argument ! 10186: jsb gtint # convert first arg to integer ! 10187: .long sar02 # jump if not integer ! 10188: # ! 10189: # HERE FOR INTEGER FIRST ARGUMENT, BUILD VCBLK ! 10190: # ! 10191: movl 4*icval(r9),r5 # load integer value ! 10192: tstl r5 # jump if zero or neg (bad dimension) ! 10193: bgtr 0f ! 10194: jmp sar10 ! 10195: 0: ! 10196: movl r5,r6 # else convert to one word, test ovfl ! 10197: bgeq 0f ! 10198: jmp sar11 ! 10199: 0: ! 10200: movl r6,r7 # copy elements for loop later on ! 10201: addl2 $vcsi$,r6 # add space for standard fields ! 10202: moval 0[r6],r6 # convert length to bytes ! 10203: cmpl r6,mxlen # fail if too large ! 10204: blssu 0f ! 10205: jmp sar11 ! 10206: 0: ! 10207: jsb alloc # allocate space for vcblk ! 10208: movl $b$vct,(r9) # store type word ! 10209: movl r6,4*vclen(r9) # set length ! 10210: movl r10,r8 # copy default value ! 10211: movl r9,r10 # copy vcblk pointer ! 10212: addl2 $4*vcvls,r10 # point to first element value ! 10213: # ! 10214: # LOOP TO SET VECTOR ELEMENTS TO DEFAULT VALUE ! 10215: # ! 10216: sar01: movl r8,(r10)+ # store one value ! 10217: sobgtr r7,sar01 # loop till all stored ! 10218: jmp exsid # exit setting idval ! 10219: #page ! 10220: # ! 10221: # ARRAY (CONTINUED) ! 10222: # ! 10223: # HERE IF FIRST ARGUMENT IS NOT AN INTEGER ! 10224: # ! 10225: sar02: movl r9,-(sp) # replace argument on stack ! 10226: jsb xscni # initialize scan of first argument ! 10227: .long er_064 # array first argument is not integer or string ! 10228: .long exnul # dummy (unused) null string exit ! 10229: movl r$xsc,-(sp) # save prototype pointer ! 10230: movl r10,-(sp) # save default value ! 10231: clrl arcdm # zero count of dimensions ! 10232: clrl arptr # zero offset to indicate pass one ! 10233: movl intv1,r5 # load integer one ! 10234: movl r5,arnel # initialize element count ! 10235: # ! 10236: # THE FOLLOWING CODE IS EXECUTED TWICE. THE FIRST TIME ! 10237: # (ARPTR EQ 0), IT IS USED TO COUNT THE NUMBER OF ELEMENTS ! 10238: # AND NUMBER OF DIMENSIONS. THE SECOND TIME (ARPTR GT 0) IS ! 10239: # USED TO ACTUALLY FILL IN THE DIM,LBD FIELDS OF THE ARBLK. ! 10240: # ! 10241: sar03: movl intv1,r5 # load one as default low bound ! 10242: movl r5,arsvl # save as low bound ! 10243: movl $ch$cl,r8 # set delimiter one = colon ! 10244: movl $ch$cm,r10 # set delimiter two = comma ! 10245: jsb xscan # scan next bound ! 10246: cmpl r6,$num01 # jump if not colon ! 10247: bnequ sar04 ! 10248: # ! 10249: # HERE WE HAVE A COLON ENDING A LOW BOUND ! 10250: # ! 10251: jsb gtint # convert low bound ! 10252: .long er_065 # array first argument lower bound is not integer ! 10253: movl 4*icval(r9),r5 # load value of low bound ! 10254: movl r5,arsvl # store low bound value ! 10255: movl $ch$cm,r8 # set delimiter one = comma ! 10256: movl r8,r10 # and delimiter two = comma ! 10257: jsb xscan # scan high bound ! 10258: #page ! 10259: # ! 10260: # ARRAY (CONTINUED) ! 10261: # ! 10262: # MERGE HERE TO PROCESS UPPER BOUND ! 10263: # ! 10264: sar04: jsb gtint # convert high bound to integer ! 10265: .long er_066 # array first argument upper bound is not integer ! 10266: movl 4*icval(r9),r5 # get high bound ! 10267: subl2 arsvl,r5 # subtract lower bound ! 10268: bvc 0f ! 10269: jmp sar10 ! 10270: 0: ! 10271: tstl r5 # bad dimension if negative ! 10272: bgeq 0f ! 10273: jmp sar10 ! 10274: 0: ! 10275: addl2 intv1,r5 # add 1 to get dimension ! 10276: bvc 0f ! 10277: jmp sar10 ! 10278: 0: ! 10279: movl arptr,r10 # load offset (also pass indicator) ! 10280: tstl r10 # jump if first pass ! 10281: beqlu sar05 ! 10282: # ! 10283: # HERE IN SECOND PASS TO STORE LBD AND DIM IN ARBLK ! 10284: # ! 10285: addl2 (sp),r10 # point to current location in arblk ! 10286: movl r5,4*cfp$i(r10) # store dimension ! 10287: movl arsvl,r5 # load low bound ! 10288: movl r5,(r10) # store low bound ! 10289: addl2 $4*ardms,arptr # bump offset to next bounds ! 10290: jmp sar06 # jump to check for end of bounds ! 10291: # ! 10292: # HERE IN PASS 1 ! 10293: # ! 10294: sar05: incl arcdm # bump dimension count ! 10295: mull2 arnel,r5 # multiply dimension by count so far ! 10296: bvc 0f ! 10297: jmp sar11 ! 10298: 0: ! 10299: movl r5,arnel # else store updated element count ! 10300: # ! 10301: # MERGE HERE AFTER PROCESSING ONE SET OF BOUNDS ! 10302: # ! 10303: sar06: tstl r6 # loop back unless end of bounds ! 10304: beqlu 0f ! 10305: jmp sar03 ! 10306: 0: ! 10307: tstl arptr # jump if end of pass 2 ! 10308: beqlu 0f ! 10309: jmp sar09 ! 10310: 0: ! 10311: #page ! 10312: # ! 10313: # ARRAY (CONTINUED) ! 10314: # ! 10315: # HERE AT END OF PASS ONE, BUILD ARBLK ! 10316: # ! 10317: movl arnel,r5 # get number of elements ! 10318: movl r5,r7 # get as addr integer, test ovflo ! 10319: bgeq 0f ! 10320: jmp sar11 ! 10321: 0: ! 10322: moval 0[r7],r7 # else convert to length in bytes ! 10323: movl $4*arsi$,r6 # set size of standard fields ! 10324: movl arcdm,r8 # set dimension count to control loop ! 10325: # ! 10326: # LOOP TO ALLOW SPACE FOR DIMENSIONS ! 10327: # ! 10328: sar07: addl2 $4*ardms,r6 # allow space for one set of bounds ! 10329: sobgtr r8,sar07 # loop back till all accounted for ! 10330: movl r6,r10 # save size (=arofs) ! 10331: # ! 10332: # NOW ALLOCATE SPACE FOR ARBLK ! 10333: # ! 10334: addl2 r7,r6 # add space for elements ! 10335: addl2 $4,r6 # allow for arpro prototype field ! 10336: cmpl r6,mxlen # fail if too large ! 10337: blssu 0f ! 10338: jmp sar11 ! 10339: 0: ! 10340: jsb alloc # else allocate arblk ! 10341: movl (sp),r7 # load default value ! 10342: movl r9,(sp) # save arblk pointer ! 10343: movl r6,r8 # save length in bytes ! 10344: ashl $-2,r6,r6 # convert length back to words ! 10345: # set counter to control loop ! 10346: # ! 10347: # LOOP TO CLEAR ENTIRE ARBLK TO DEFAULT VALUE ! 10348: # ! 10349: sar08: movl r7,(r9)+ # set one word ! 10350: sobgtr r6,sar08 # loop till all set ! 10351: #page ! 10352: # ! 10353: # ARRAY (CONTINUED) ! 10354: # ! 10355: # NOW SET INITIAL FIELDS OF ARBLK ! 10356: # ! 10357: movl (sp)+,r9 # reload arblk pointer ! 10358: movl (sp),r7 # load prototype ! 10359: movl $b$art,(r9) # set type word ! 10360: movl r8,4*arlen(r9) # store length in bytes ! 10361: clrl 4*idval(r9) # zero id till we get it built ! 10362: movl r10,4*arofs(r9) # set prototype field ptr ! 10363: movl arcdm,4*arndm(r9)# set number of dimensions ! 10364: movl r9,r8 # save arblk pointer ! 10365: addl2 r10,r9 # point to prototype field ! 10366: movl r7,(r9) # store prototype ptr in arblk ! 10367: movl $4*arlbd,arptr # set offset for pass 2 bounds scan ! 10368: movl r7,r$xsc # reset string pointer for xscan ! 10369: movl r8,(sp) # store arblk pointer on stack ! 10370: clrl xsofs # reset offset ptr to start of string ! 10371: jmp sar03 # jump back to rescan bounds ! 10372: # ! 10373: # HERE AFTER FILLING IN BOUNDS INFORMATION (END PASS TWO) ! 10374: # ! 10375: sar09: movl (sp)+,r9 # reload pointer to arblk ! 10376: jmp exsid # exit setting idval ! 10377: # ! 10378: # HERE FOR BAD DIMENSION ! 10379: # ! 10380: sar10: jmp er_067 # array dimension is zero,negative or out of range ! 10381: # ! 10382: # HERE IF ARRAY IS TOO LARGE ! 10383: # ! 10384: sar11: jmp er_068 # array size exceeds maximum permitted ! 10385: #page ! 10386: # ! 10387: # BUFFER ! 10388: # ! 10389: s$buf: # entry point ! 10390: movl (sp)+,r10 # get initial value ! 10391: movl (sp)+,r9 # get requested allocation ! 10392: jsb gtint # convert to integer ! 10393: .long er_269 # buffer first argument is not integer ! 10394: movl 4*icval(r9),r5 # get value ! 10395: tstl r5 # branch if negative or zero ! 10396: bleq sbf01 ! 10397: movl r5,r6 # move with overflow check ! 10398: bgeq 0f ! 10399: jmp sbf02 ! 10400: 0: ! 10401: jsb alobf # allocate the buffer ! 10402: jsb apndb # copy it in ! 10403: .long er_270 # buffer second argument is not string or buffer ! 10404: .long er_271 # buffer initial value too big for allocation ! 10405: jmp exsid # exit setting idval ! 10406: # ! 10407: # HERE FOR INVALID ALLOCATION SIZE ! 10408: # ! 10409: sbf01: jmp er_272 # buffer first argument is not positive ! 10410: # ! 10411: # HERE FOR ALLOCATION SIZE INTEGER OVERFLOW ! 10412: # ! 10413: sbf02: jmp er_273 # buffer size is too big ! 10414: #page ! 10415: # ! 10416: # BREAK ! 10417: # ! 10418: s$brk: # entry point ! 10419: movl $p$bks,r7 # set pcode for single char case ! 10420: movl $p$brk,r10 # pcode for multi-char case ! 10421: movl $p$bkd,r8 # pcode for expression case ! 10422: jsb patst # call common routine to build node ! 10423: .long er_069 # break argument is not string or expression ! 10424: jmp exixr # jump for next code word ! 10425: #page ! 10426: # ! 10427: # BREAKX ! 10428: # ! 10429: # BREAKX IS A COMPOUND PATTERN. SEE DESCRIPTION AT START ! 10430: # OF PATTERN MATCHING SECTION FOR STRUCTURE FORMED. ! 10431: # ! 10432: s$bkx: # entry point ! 10433: movl $p$bks,r7 # pcode for single char argument ! 10434: movl $p$brk,r10 # pcode for multi-char argument ! 10435: movl $p$bxd,r8 # pcode for expression case ! 10436: jsb patst # call common routine to build node ! 10437: .long er_070 # breakx argument is not string or expression ! 10438: # ! 10439: # NOW HOOK BREAKX NODE ON AT FRONT END ! 10440: # ! 10441: movl r9,-(sp) # save ptr to break node ! 10442: movl $p$bkx,r7 # set pcode for breakx node ! 10443: jsb pbild # build it ! 10444: movl (sp),4*pthen(r9)# set break node as successor ! 10445: movl $p$alt,r7 # set pcode for alternation node ! 10446: jsb pbild # build (parm1=alt=breakx node) ! 10447: movl r9,r6 # save ptr to alternation node ! 10448: movl (sp),r9 # point to break node ! 10449: movl r6,4*pthen(r9) # set alternate node as successor ! 10450: jmp exits # exit with result on stack ! 10451: #page ! 10452: # ! 10453: # CHAR ! 10454: # ! 10455: s$chr: # entry point ! 10456: jsb gtsmi # convert arg to integer ! 10457: .long er_281 # char argument not integer ! 10458: .long schr1 # too big error exit ! 10459: cmpl r8,$cfp$a # see if out of range of host set ! 10460: bgequ schr1 ! 10461: movl $num01,r6 # if not set scblk allocation ! 10462: movl r8,r7 # save char code ! 10463: jsb alocs # allocate 1 bau scblk ! 10464: movl r9,r10 # copy scblk pointer ! 10465: movab cfp$f(r10),r10 # get set to stuff char ! 10466: movb r7,(r10)+ # stuff it ! 10467: clrl r10 # clear slop in xl ! 10468: jmp exixr # exit with scblk pointer ! 10469: # ! 10470: # HERE IF CHAR ARGUMENT IS OUT OF RANGE ! 10471: # ! 10472: schr1: jmp er_282 # char argument not in range ! 10473: #page ! 10474: # ! 10475: # CLEAR ! 10476: # ! 10477: s$clr: # entry point ! 10478: jsb xscni # initialize to scan argument ! 10479: .long er_071 # clear argument is not string ! 10480: .long sclr2 # jump if null ! 10481: # ! 10482: # LOOP TO SCAN OUT NAMES IN FIRST ARGUMENT. VARIABLES IN ! 10483: # THE LIST ARE FALGGED BY SETTING VRGET OF VRBLK TO ZERO. ! 10484: # ! 10485: sclr1: movl $ch$cm,r8 # set delimiter one = comma ! 10486: movl r8,r10 # delimiter two = comma ! 10487: jsb xscan # scan next variable name ! 10488: jsb gtnvr # locate vrblk ! 10489: .long er_072 # clear argument has null variable name ! 10490: clrl 4*vrget(r9) # else flag by zeroing vrget field ! 10491: tstl r6 # loop back if stopped by comma ! 10492: bnequ sclr1 ! 10493: # ! 10494: # HERE AFTER FLAGGING VARIABLES IN ARGUMENT LIST ! 10495: # ! 10496: sclr2: movl hshtb,r7 # point to start of hash table ! 10497: # ! 10498: # LOOP THROUGH SLOTS IN HASH TABLE ! 10499: # ! 10500: sclr3: cmpl r7,hshte # exit returning null if none left ! 10501: bnequ 0f ! 10502: jmp exnul ! 10503: 0: ! 10504: movl r7,r9 # else copy slot pointer ! 10505: addl2 $4,r7 # bump slot pointer ! 10506: subl2 $4*vrnxt,r9 # set offset to merge into loop ! 10507: # ! 10508: # LOOP THROUGH VRBLKS ON ONE HASH CHAIN ! 10509: # ! 10510: sclr4: movl 4*vrnxt(r9),r9 # point to next vrblk on chain ! 10511: tstl r9 # jump for next bucket if chain end ! 10512: beqlu sclr3 ! 10513: tstl 4*vrget(r9) # jump if not flagged ! 10514: bnequ sclr5 ! 10515: #page ! 10516: # ! 10517: # CLEAR (CONTINUED) ! 10518: # ! 10519: # HERE FOR FLAGGED VARIABLE, DO NOT SET VALUE TO NULL ! 10520: # ! 10521: jsb setvr # for flagged var, restore vrget ! 10522: jmp sclr4 # and loop back for next vrblk ! 10523: # ! 10524: # HERE TO SET VALUE OF A VARIABLE TO NULL ! 10525: # PRROTECTED VARIABLES (ARB, ETC) ARE EXEMPT ! 10526: # ! 10527: sclr5: cmpl 4*vrsto(r9),$b$vre # check for protected variable (reg05) ! 10528: beqlu sclr4 ! 10529: movl r9,r10 # copy vrblk pointer (reg05) ! 10530: # ! 10531: # LOOP TO LOCATE VALUE AT END OF POSSIBLE TRBLK CHAIN ! 10532: # ! 10533: sclr6: movl r10,r6 # save block pointer ! 10534: movl 4*vrval(r10),r10# load next value field ! 10535: cmpl (r10),$b$trt # loop back if trapped ! 10536: beqlu sclr6 ! 10537: # ! 10538: # NOW STORE THE NULL VALUE ! 10539: # ! 10540: movl r6,r10 # restore block pointer ! 10541: movl $nulls,4*vrval(r10) # store null constant value ! 10542: jmp sclr4 # loop back for next vrblk ! 10543: #page ! 10544: # ! 10545: # CODE ! 10546: # ! 10547: s$cod: # entry point ! 10548: movl (sp)+,r9 # load argument ! 10549: jsb gtcod # convert to code ! 10550: .long exfal # fail if conversion is impossible ! 10551: jmp exixr # else return code as result ! 10552: #page ! 10553: # ! 10554: # COLLECT ! 10555: # ! 10556: s$col: # entry point ! 10557: movl (sp)+,r9 # load argument ! 10558: jsb gtint # convert to integer ! 10559: .long er_073 # collect argument is not integer ! 10560: movl 4*icval(r9),r5 # load collect argument ! 10561: movl r5,clsvi # save collect argument ! 10562: clrl r7 # set no move up ! 10563: jsb gbcol # perform garbage collection ! 10564: movl dname,r6 # point to end of memory ! 10565: subl2 dnamp,r6 # subtract next location ! 10566: ashl $-2,r6,r6 # convert bytes to words ! 10567: movl r6,r5 # convert words available as integer ! 10568: subl2 clsvi,r5 # subtract argument ! 10569: bvc 0f ! 10570: jmp exfal ! 10571: 0: ! 10572: tstl r5 # fail if not enough ! 10573: bgeq 0f ! 10574: jmp exfal ! 10575: 0: ! 10576: addl2 clsvi,r5 # else recompute available ! 10577: jmp exint # and exit with integer result ! 10578: #page ! 10579: # ! 10580: # CONVERT ! 10581: # ! 10582: s$cnv: # entry point ! 10583: jsb gtstg # convert second argument to string ! 10584: .long er_074 # convert second argument is not string ! 10585: jsb flstg # fold lower case to upper case ! 10586: movl (sp),r10 # load first argument ! 10587: cmpl (r10),$b$pdt # jump if not program defined ! 10588: bnequ scv01 ! 10589: # ! 10590: # HERE FOR PROGRAM DEFINED DATATYPE ! 10591: # ! 10592: movl 4*pddfp(r10),r10# point to dfblk ! 10593: movl 4*dfnam(r10),r10# load datatype name ! 10594: jsb ident # compare with second arg ! 10595: .long exits # exit if ident with arg as result ! 10596: jmp exfal # else fail ! 10597: # ! 10598: # HERE IF NOT PROGRAM DEFINED DATATYPE ! 10599: # ! 10600: scv01: movl r9,-(sp) # save string argument ! 10601: movl $svctb,r10 # point to table of names to compare ! 10602: clrl r7 # initialize counter ! 10603: movl r6,r8 # save length of argument string ! 10604: # ! 10605: # LOOP THROUGH TABLE ENTRIES ! 10606: # ! 10607: scv02: movl (r10)+,r9 # load next table entry, bump pointer ! 10608: tstl r9 # fail if zero marking end of list ! 10609: bnequ 0f ! 10610: jmp exfal ! 10611: 0: ! 10612: cmpl r8,4*sclen(r9) # jump if wrong length ! 10613: beqlu 0f ! 10614: jmp scv05 ! 10615: 0: ! 10616: movl r10,cnvtp # else store table pointer ! 10617: movab cfp$f(r9),r9 # point to chars of table entry ! 10618: movl (sp),r10 # load pointer to string argument ! 10619: movab cfp$f(r10),r10 # point to chars of string arg ! 10620: movl r8,r6 # set number of chars to compare ! 10621: jsb sbcmc # compare, jump if no match ! 10622: .long scv04 ! 10623: .long scv04 ! 10624: #page ! 10625: # ! 10626: # CONVERT (CONTINUED) ! 10627: # ! 10628: # HERE WE HAVE A MATCH ! 10629: # ! 10630: scv03: movl r7,r10 # copy entry number ! 10631: addl2 $4,sp # pop string arg off stack ! 10632: movl (sp)+,r9 # load first argument ! 10633: casel r10,$0,$cnvtt # jump to appropriate routine ! 10634: 5: ! 10635: .word scv06-5b # string ! 10636: .word scv07-5b # integer ! 10637: .word scv09-5b # name ! 10638: .word scv10-5b # pattern ! 10639: .word scv11-5b # array ! 10640: .word scv19-5b # table ! 10641: .word scv25-5b # expression ! 10642: .word scv26-5b # code ! 10643: .word scv27-5b # numeric ! 10644: .word scv08-5b # real ! 10645: .word scv28-5b # buffer ! 10646: #esw # end of switch table ! 10647: # ! 10648: # HERE IF NO MATCH WITH TABLE ENTRY ! 10649: # ! 10650: scv04: movl cnvtp,r10 # restore table pointer, merge ! 10651: # ! 10652: # MERGE HERE IF LENGTHS DID NOT MATCH ! 10653: # ! 10654: scv05: incl r7 # bump entry number ! 10655: jmp scv02 # loop back to check next entry ! 10656: # ! 10657: # HERE TO CONVERT TO STRING ! 10658: # ! 10659: scv06: movl r9,-(sp) # replace string argument on stack ! 10660: jsb gtstg # convert to string ! 10661: .long exfal # fail if conversion not possible ! 10662: jmp exixr # else return string ! 10663: #page ! 10664: # ! 10665: # CONVERT (CONTINUED) ! 10666: # ! 10667: # HERE TO CONVERT TO INTEGER ! 10668: # ! 10669: scv07: jsb gtint # convert to integer ! 10670: .long exfal # fail if conversion not possible ! 10671: jmp exixr # else return integer ! 10672: # ! 10673: # HERE TO CONVERT TO REAL ! 10674: # ! 10675: scv08: jsb gtrea # convert to real ! 10676: .long exfal # fail if conversion not possible ! 10677: jmp exixr # else return real ! 10678: # ! 10679: # HERE TO CONVERT TO NAME ! 10680: # ! 10681: scv09: cmpl (r9),$b$nml # return if already a name ! 10682: bnequ 0f ! 10683: jmp exixr ! 10684: 0: ! 10685: jsb gtnvr # else try string to name convert ! 10686: .long exfal # fail if conversion not possible ! 10687: jmp exvnm # else exit building nmblk for vrblk ! 10688: # ! 10689: # HERE TO CONVERT TO PATTERN ! 10690: # ! 10691: scv10: jsb gtpat # convert to pattern ! 10692: .long exfal # fail if conversion not possible ! 10693: jmp exixr # else return pattern ! 10694: # ! 10695: # CONVERT TO ARRAY ! 10696: # ! 10697: scv11: jsb gtarr # get an array ! 10698: .long exfal # fail if not convertible ! 10699: jmp exsid # exit setting id field ! 10700: # ! 10701: # CONVERT TO TABLE ! 10702: # ! 10703: scv19: movl (r9),r6 # load first word of block ! 10704: movl r9,-(sp) # replace arblk pointer on stack ! 10705: cmpl r6,$b$tbt # return arg if already a table ! 10706: bnequ 0f ! 10707: jmp exits ! 10708: 0: ! 10709: cmpl r6,$b$art # else fail if not an array ! 10710: beqlu 0f ! 10711: jmp exfal ! 10712: 0: ! 10713: #page ! 10714: # ! 10715: # CONVERT (CONTINUED) ! 10716: # ! 10717: # HERE TO CONVERT AN ARRAY TO TABLE ! 10718: # ! 10719: cmpl 4*arndm(r9),$num02 # fail if not 2-dim array ! 10720: beqlu 0f ! 10721: jmp exfal ! 10722: 0: ! 10723: movl 4*ardm2(r9),r5 # load dim 2 ! 10724: subl2 intv2,r5 # subtract 2 to compare ! 10725: tstl r5 # fail if dim2 not 2 ! 10726: beql 0f ! 10727: jmp exfal ! 10728: 0: ! 10729: # ! 10730: # HERE WE HAVE AN ARBLK OF THE RIGHT SHAPE ! 10731: # ! 10732: movl 4*ardim(r9),r5 # load dim 1 (number of elements) ! 10733: movl r5,r6 # get as one word integer ! 10734: movl r6,r7 # copy to control loop ! 10735: addl2 $tbsi$,r6 # add space for standard fields ! 10736: moval 0[r6],r6 # convert length to bytes ! 10737: jsb alloc # allocate space for tbblk ! 10738: movl r9,r8 # copy tbblk pointer ! 10739: movl r9,-(sp) # save tbblk pointer ! 10740: movl $b$tbt,(r9)+ # store type word ! 10741: clrl (r9)+ # store zero for idval for now ! 10742: movl r6,(r9)+ # store length ! 10743: movl $nulls,(r9)+ # null initial lookup value ! 10744: # ! 10745: # LOOP TO INITIALIZE BUCKET PTRS TO POINT TO TABLE ! 10746: # ! 10747: scv20: movl r8,(r9)+ # set bucket ptr to point to tbblk ! 10748: sobgtr r7,scv20 # loop till all initialized ! 10749: movl $4*arvl2,r7 # set offset to first arblk element ! 10750: # ! 10751: # LOOP TO COPY ELEMENTS FROM ARRAY TO TABLE ! 10752: # ! 10753: scv21: movl 4*1(sp),r10 # point to arblk ! 10754: cmpl r7,4*arlen(r10) # jump if all moved ! 10755: beqlu scv24 ! 10756: addl2 r7,r10 # else point to current location ! 10757: addl2 $4*num02,r7 # bump offset ! 10758: movl (r10),r9 # load subscript name ! 10759: subl2 $4,r10 # adjust ptr to merge (trval=1+1) ! 10760: #page ! 10761: # ! 10762: # CONVERT (CONTINUED) ! 10763: # ! 10764: # LOOP TO CHASE DOWN TRBLK CHAIN FOR VALUE ! 10765: # ! 10766: scv22: movl 4*trval(r10),r10# point to next value ! 10767: cmpl (r10),$b$trt # loop back if trapped ! 10768: beqlu scv22 ! 10769: # ! 10770: # HERE WITH NAME IN XR, VALUE IN XL ! 10771: # ! 10772: scv23: movl r10,-(sp) # stack value ! 10773: movl 4*1(sp),r10 # load tbblk pointer ! 10774: jsb tfind # build teblk (note wb gt 0 by name) ! 10775: .long exfal # fail if acess fails ! 10776: movl (sp)+,4*teval(r10) # store value in teblk ! 10777: jmp scv21 # loop back for next element ! 10778: # ! 10779: # HERE AFTER MOVING ALL ELEMENTS TO TBBLK ! 10780: # ! 10781: scv24: movl (sp)+,r9 # load tbblk pointer ! 10782: addl2 $4,sp # pop arblk pointer ! 10783: jmp exsid # exit setting idval ! 10784: # ! 10785: # CONVERT TO EXPRESSION ! 10786: # ! 10787: scv25: jsb gtexp # convert to expression ! 10788: .long exfal # fail if conversion not possible ! 10789: jmp exixr # else return expression ! 10790: # ! 10791: # CONVERT TO CODE ! 10792: # ! 10793: scv26: jsb gtcod # convert to code ! 10794: .long exfal # fail if conversion is not possible ! 10795: jmp exixr # else return code ! 10796: # ! 10797: # CONVERT TO NUMERIC ! 10798: # ! 10799: scv27: jsb gtnum # convert to numeric ! 10800: .long exfal # fail if unconvertible ! 10801: jmp exixr # return number ! 10802: #page ! 10803: # ! 10804: # CONVERT TO BUFFER ! 10805: # ! 10806: scv28: movl r9,-(sp) # stack string for procedure ! 10807: jsb gtstg # convert to string ! 10808: .long exfal # fail if conversion not possible ! 10809: movl r9,r10 # save string pointer ! 10810: jsb alobf # allocate buffer of same size ! 10811: jsb apndb # copy in the string ! 10812: .long invalid$ # already string - cant fail to cnv ! 10813: .long invalid$ # must be enough room ! 10814: jmp exsid # exit setting idval field ! 10815: #page ! 10816: # ! 10817: # COPY ! 10818: # ! 10819: s$cop: # entry point ! 10820: jsb copyb # copy the block ! 10821: .long exits # return if no idval field ! 10822: jmp exsid # exit setting id value ! 10823: #page ! 10824: # ! 10825: # DATA ! 10826: # ! 10827: s$dat: # entry point ! 10828: jsb xscni # prepare to scan argument ! 10829: .long er_075 # data argument is not string ! 10830: .long er_076 # data argument is null ! 10831: # ! 10832: # SCAN OUT DATATYPE NAME ! 10833: # ! 10834: movl $ch$pp,r8 # delimiter one = left paren ! 10835: movl r8,r10 # delimiter two = left paren ! 10836: jsb xscan # scan datatype name ! 10837: tstl r6 # skip if left paren found ! 10838: bnequ sdat1 ! 10839: jmp er_077 # data argument is missing a left paren ! 10840: # ! 10841: # HERE AFTER SCANNING DATATYPE NAME ! 10842: # ! 10843: sdat1: movl 4*sclen(r9),r6 # get length ! 10844: jsb flstg # fold lower case to upper case ! 10845: movl r9,r10 # save name ptr ! 10846: movl 4*sclen(r9),r6 # get length ! 10847: movab 3+(4*scsi$)(r6),r6 # compute space needed ! 10848: bicl2 $3,r6 ! 10849: jsb alost # request static store for name ! 10850: movl r9,-(sp) # save datatype name ! 10851: jsb sbmvw # copy name to static ! 10852: movl (sp),r9 # get name ptr ! 10853: clrl r10 # scrub dud register ! 10854: jsb gtnvr # locate vrblk for datatype name ! 10855: .long er_078 # data argument has null datatype name ! 10856: movl r9,datdv # save vrblk pointer for datatype ! 10857: movl sp,datxs # store starting stack value ! 10858: clrl r7 # zero count of field names ! 10859: # ! 10860: # LOOP TO SCAN FIELD NAMES AND STACK VRBLK POINTERS ! 10861: # ! 10862: sdat2: movl $ch$rp,r8 # delimiter one = right paren ! 10863: movl $ch$cm,r10 # delimiter two = comma ! 10864: jsb xscan # scan next field name ! 10865: tstl r6 # jump if delimiter found ! 10866: bnequ sdat3 ! 10867: jmp er_079 # data argument is missing a right paren ! 10868: # ! 10869: # HERE AFTER SCANNING OUT ONE FIELD NAME ! 10870: # ! 10871: sdat3: jsb gtnvr # locate vrblk for field name ! 10872: .long er_080 # data argument has null field name ! 10873: movl r9,-(sp) # stack vrblk pointer ! 10874: incl r7 # increment counter ! 10875: cmpl r6,$num02 # loop back if stopped by comma ! 10876: beqlu sdat2 ! 10877: #page ! 10878: # ! 10879: # DATA (CONTINUED) ! 10880: # ! 10881: # NOW BUILD THE DFBLK ! 10882: # ! 10883: movl $dfsi$,r6 # set size of dfblk standard fields ! 10884: addl2 r7,r6 # add number of fields ! 10885: moval 0[r6],r6 # convert length to bytes ! 10886: movl r7,r8 # preserve no. of fields ! 10887: jsb alost # allocate space for dfblk ! 10888: movl r8,r7 # get no of fields ! 10889: movl datxs,r10 # point to start of stack ! 10890: movl (r10),r8 # load datatype name ! 10891: movl r9,(r10) # save dfblk pointer on stack ! 10892: movl $b$dfc,(r9)+ # store type word ! 10893: movl r7,(r9)+ # store number of fields (fargs) ! 10894: movl r6,(r9)+ # store length (dflen) ! 10895: subl2 $4*pddfs,r6 # compute pdblk length (for dfpdl) ! 10896: movl r6,(r9)+ # store pdblk length (dfpdl) ! 10897: movl r8,(r9)+ # store datatype name (dfnam) ! 10898: movl r7,r8 # copy number of fields ! 10899: # ! 10900: # LOOP TO MOVE FIELD NAME VRBLK POINTERS TO DFBLK ! 10901: # ! 10902: sdat4: movl -(r10),(r9)+ # move one field name vrblk pointer ! 10903: sobgtr r8,sdat4 # loop till all moved ! 10904: # ! 10905: # NOW DEFINE THE DATATYPE FUNCTION ! 10906: # ! 10907: movl r6,r8 # copy length of pdblk for later loop ! 10908: movl datdv,r9 # point to vrblk ! 10909: movl datxs,r10 # point back on stack ! 10910: movl (r10),r10 # load dfblk pointer ! 10911: jsb dffnc # define function ! 10912: #page ! 10913: # ! 10914: # DATA (CONTINUED) ! 10915: # ! 10916: # LOOP TO BUILD FFBLKS ! 10917: # ! 10918: # ! 10919: # NOTICE THAT THE FFBLKS ARE CONSTRUCTED IN REVERSE ORDER ! 10920: # SO THAT THE REQUIRED OFFSETS CAN BE OBTAINED FROM ! 10921: # SUCCESSIVE DECREMENTATION OF THE PDBLK LENGTH (IN WC). ! 10922: # ! 10923: sdat5: movl $4*ffsi$,r6 # set length of ffblk ! 10924: jsb alloc # allocate space for ffblk ! 10925: movl $b$ffc,(r9) # set type word ! 10926: movl $num01,4*fargs(r9) # store fargs (always one) ! 10927: movl datxs,r10 # point back on stack ! 10928: movl (r10),4*ffdfp(r9)# copy dfblk ptr to ffblk ! 10929: subl2 $4,r8 # decrement old dfpdl to get next ofs ! 10930: movl r8,4*ffofs(r9) # set offset to this field ! 10931: clrl 4*ffnxt(r9) # tentatively set zero forward ptr ! 10932: movl r9,r10 # copy ffblk pointer for dffnc ! 10933: movl (sp),r9 # load vrblk pointer for field ! 10934: movl 4*vrfnc(r9),r9 # load current function pointer ! 10935: cmpl (r9),$b$ffc # skip if not currently a field func ! 10936: bnequ sdat6 ! 10937: # ! 10938: # HERE WE MUST CHAIN AN OLD FFBLK PTR TO PRESERVE IT IN THE ! 10939: # CASE OF MULTIPLE FIELD FUNCTIONS WITH THE SAME NAME ! 10940: # ! 10941: movl r9,4*ffnxt(r10) # link new ffblk to previous chain ! 10942: # ! 10943: # MERGE HERE TO DEFINE FIELD FUNCTION ! 10944: # ! 10945: sdat6: movl (sp)+,r9 # load vrblk pointer ! 10946: jsb dffnc # define field function ! 10947: cmpl sp,datxs # loop back till all done ! 10948: bnequ sdat5 ! 10949: addl2 $4,sp # pop dfblk pointer ! 10950: jmp exnul # return with null result ! 10951: #page ! 10952: # ! 10953: # DATATYPE ! 10954: # ! 10955: s$dtp: # entry point ! 10956: movl (sp)+,r9 # load argument ! 10957: jsb dtype # get datatype ! 10958: jmp exixr # and return it as result ! 10959: #page ! 10960: # ! 10961: # DATE ! 10962: # ! 10963: s$dte: # entry point ! 10964: jsb sysdt # call system date routine ! 10965: movl 4*1(r10),r6 # load length for sbstr ! 10966: tstl r6 # return null if length is zero ! 10967: bnequ 0f ! 10968: jmp exnul ! 10969: 0: ! 10970: clrl r7 # set zero offset ! 10971: jsb sbstr # use sbstr to build scblk ! 10972: jmp exixr # return date string ! 10973: #page ! 10974: # ! 10975: # DEFINE ! 10976: # ! 10977: s$def: # entry point ! 10978: movl (sp)+,r9 # load second argument ! 10979: clrl deflb # zero label pointer in case null ! 10980: cmpl r9,$nulls # jump if null second argument ! 10981: beqlu sdf01 ! 10982: jsb gtnvr # else find vrblk for label ! 10983: .long sdf13 # jump if not a variable name ! 10984: movl r9,deflb # else set specified entry ! 10985: # ! 10986: # SCAN FUNCTION NAME ! 10987: # ! 10988: sdf01: jsb xscni # prepare to scan first argument ! 10989: .long er_081 # define first argument is not string ! 10990: .long er_082 # define first argument is null ! 10991: movl $ch$pp,r8 # delimiter one = left paren ! 10992: movl r8,r10 # delimiter two = left paren ! 10993: jsb xscan # scan out function name ! 10994: tstl r6 # jump if left paren found ! 10995: bnequ sdf02 ! 10996: jmp er_083 # define first argument is missing a left paren ! 10997: # ! 10998: # HERE AFTER SCANNING OUT FUNCTION NAME ! 10999: # ! 11000: sdf02: jsb gtnvr # get variable name ! 11001: .long er_084 # define first argument has null function name ! 11002: movl r9,defvr # save vrblk pointer for function nam ! 11003: clrl r7 # zero count of arguments ! 11004: movl sp,defxs # save initial stack pointer ! 11005: tstl deflb # jump if second argument given ! 11006: bnequ sdf03 ! 11007: movl r9,deflb # else default is function name ! 11008: # ! 11009: # LOOP TO SCAN ARGUMENT NAMES AND STACK VRBLK POINTERS ! 11010: # ! 11011: sdf03: movl $ch$rp,r8 # delimiter one = right paren ! 11012: movl $ch$cm,r10 # delimiter two = comma ! 11013: jsb xscan # scan out next argument name ! 11014: tstl r6 # skip if delimiter found ! 11015: bnequ sdf04 ! 11016: jmp er_085 # null arg name or missing ) in define first arg. ! 11017: #page ! 11018: # ! 11019: # DEFINE (CONTINUED) ! 11020: # ! 11021: # HERE AFTER SCANNING AN ARGUMENT NAME ! 11022: # ! 11023: sdf04: cmpl r9,$nulls # skip if non-null ! 11024: bnequ sdf05 ! 11025: tstl r7 # ignore null if case of no arguments ! 11026: beqlu sdf06 ! 11027: # ! 11028: # HERE AFTER DEALING WITH THE CASE OF NO ARGUMENTS ! 11029: # ! 11030: sdf05: jsb gtnvr # get vrblk pointer ! 11031: .long sdf03 # loop back to ignore null name ! 11032: movl r9,-(sp) # stack argument vrblk pointer ! 11033: incl r7 # increment counter ! 11034: cmpl r6,$num02 # loop back if stopped by a comma ! 11035: beqlu sdf03 ! 11036: # ! 11037: # HERE AFTER SCANNING OUT FUNCTION ARGUMENT NAMES ! 11038: # ! 11039: sdf06: movl r7,defna # save number of arguments ! 11040: clrl r7 # zero count of locals ! 11041: # ! 11042: # LOOP TO SCAN LOCAL NAMES AND STACK VRBLK POINTERS ! 11043: # ! 11044: sdf07: movl $ch$cm,r8 # set delimiter one = comma ! 11045: movl r8,r10 # set delimiter two = comma ! 11046: jsb xscan # scan out next local name ! 11047: cmpl r9,$nulls # skip if non-null ! 11048: bnequ sdf08 ! 11049: tstl r7 # ignore null if case of no locals ! 11050: beqlu sdf09 ! 11051: # ! 11052: # HERE AFTER SCANNING OUT A LOCAL NAME ! 11053: # ! 11054: sdf08: jsb gtnvr # get vrblk pointer ! 11055: .long sdf07 # loop back to ignore null name ! 11056: incl r7 # if ok, increment count ! 11057: movl r9,-(sp) # stack vrblk pointer ! 11058: tstl r6 # loop back if stopped by a comma ! 11059: bnequ sdf07 ! 11060: #page ! 11061: # ! 11062: # DEFINE (CONTINUED) ! 11063: # ! 11064: # HERE AFTER SCANNING LOCALS, BUILD PFBLK ! 11065: # ! 11066: sdf09: movl r7,r6 # copy count of locals ! 11067: addl2 defna,r6 # add number of arguments ! 11068: movl r6,r8 # set sum args+locals as loop count ! 11069: addl2 $pfsi$,r6 # add space for standard fields ! 11070: moval 0[r6],r6 # convert length to bytes ! 11071: jsb alloc # allocate space for pfblk ! 11072: movl r9,r10 # save pointer to pfblk ! 11073: movl $b$pfc,(r9)+ # store first word ! 11074: movl defna,(r9)+ # store number of arguments ! 11075: movl r6,(r9)+ # store length (pflen) ! 11076: movl defvr,(r9)+ # store vrblk ptr for function name ! 11077: movl r7,(r9)+ # store number of locals ! 11078: clrl (r9)+ # deal with label later ! 11079: clrl (r9)+ # zero pfctr ! 11080: clrl (r9)+ # zero pfrtr ! 11081: tstl r8 # skip if no args or locals ! 11082: beqlu sdf11 ! 11083: movl r10,r6 # keep pfblk pointer ! 11084: movl defxs,r10 # point before arguments ! 11085: # get count of args+locals for loop ! 11086: # ! 11087: # LOOP TO MOVE LOCALS AND ARGS TO PFBLK ! 11088: # ! 11089: sdf10: movl -(r10),(r9)+ # store one entry and bump pointers ! 11090: sobgtr r8,sdf10 # loop till all stored ! 11091: movl r6,r10 # recover pfblk pointer ! 11092: #page ! 11093: # ! 11094: # DEFINE (CONTINUED) ! 11095: # ! 11096: # NOW DEAL WITH LABEL ! 11097: # ! 11098: sdf11: movl defxs,sp # pop stack ! 11099: movl deflb,r9 # point to vrblk for label ! 11100: movl 4*vrlbl(r9),r9 # load label pointer ! 11101: cmpl (r9),$b$trt # skip if not trapped ! 11102: bnequ sdf12 ! 11103: movl 4*trlbl(r9),r9 # else point to real label ! 11104: # ! 11105: # HERE AFTER LOCATING REAL LABEL POINTER ! 11106: # ! 11107: sdf12: cmpl r9,$stndl # jump if label is not defined ! 11108: beqlu sdf13 ! 11109: movl r9,4*pfcod(r10) # else store label pointer ! 11110: movl defvr,r9 # point back to vrblk for function ! 11111: jsb dffnc # define function ! 11112: jmp exnul # and exit returning null ! 11113: # ! 11114: # HERE FOR ERRONEOUS LABEL ! 11115: # ! 11116: sdf13: jmp er_086 # define function entry point is not defined label ! 11117: #page ! 11118: # ! 11119: # DETACH ! 11120: # ! 11121: s$det: # entry point ! 11122: movl (sp)+,r9 # load argument ! 11123: jsb gtvar # locate variable ! 11124: .long er_087 # detach argument is not appropriate name ! 11125: jsb dtach # detach i/o association from name ! 11126: jmp exnul # return null result ! 11127: #page ! 11128: # ! 11129: # DIFFER ! 11130: # ! 11131: s$dif: # entry point ! 11132: movl (sp)+,r9 # load second argument ! 11133: movl (sp)+,r10 # load first argument ! 11134: jsb ident # call ident comparison routine ! 11135: .long exfal # fail if ident ! 11136: jmp exnul # return null if differ ! 11137: #page ! 11138: # ! 11139: # DUMP ! 11140: # ! 11141: s$dmp: # entry point ! 11142: jsb gtsmi # load dump arg as small integer ! 11143: .long er_088 # dump argument is not integer ! 11144: .long er_089 # dump argument is negative or too large ! 11145: jsb dumpr # else call dump routine ! 11146: jmp exnul # and return null as result ! 11147: #page ! 11148: # ! 11149: # DUPL ! 11150: # ! 11151: s$dup: # entry point ! 11152: jsb gtsmi # get second argument as small intege ! 11153: .long er_090 # dupl second argument is not integer ! 11154: .long sdup7 # jump if negative ot too big ! 11155: movl r9,r7 # save duplication factor ! 11156: jsb gtstg # get first arg as string ! 11157: .long sdup4 # jump if not a string ! 11158: # ! 11159: # HERE FOR CASE OF DUPLICATION OF A STRING ! 11160: # ! 11161: movl r6,r5 # acquire length as integer ! 11162: movl r5,dupsi # save for the moment ! 11163: movl r7,r5 # get duplication factor as integer ! 11164: mull2 dupsi,r5 # form product ! 11165: bvs sdup3 ! 11166: tstl r5 # return null if result length = 0 ! 11167: bneq 0f ! 11168: jmp exnul ! 11169: 0: ! 11170: movl r5,r6 # get as addr integer, check ovflo ! 11171: bgeq 0f ! 11172: jmp sdup3 ! 11173: 0: ! 11174: # ! 11175: # MERGE HERE WITH RESULT LENGTH IN WA ! 11176: # ! 11177: sdup1: movl r9,r10 # save string pointer ! 11178: jsb alocs # allocate space for string ! 11179: movl r9,-(sp) # save as result pointer ! 11180: movl r10,r8 # save pointer to argument string ! 11181: movab cfp$f(r9),r9 # prepare to store chars of result ! 11182: # set counter to control loop ! 11183: # ! 11184: # LOOP THROUGH DUPLICATIONS ! 11185: # ! 11186: sdup2: movl r8,r10 # point back to argument string ! 11187: movl 4*sclen(r10),r6 # get number of characters ! 11188: movab cfp$f(r10),r10 # point to chars in argument string ! 11189: jsb sbmvc # move characters to result string ! 11190: sobgtr r7,sdup2 # loop till all duplications done ! 11191: jmp exits # then exit for next code word ! 11192: #page ! 11193: # ! 11194: # DUPL (CONTINUED) ! 11195: # ! 11196: # HERE IF TOO LARGE, SET MAX LENGTH AND LET ALOCS CATCH IT ! 11197: # ! 11198: sdup3: movl dname,r6 # set impossible length for alocs ! 11199: jmp sdup1 # merge back ! 11200: # ! 11201: # HERE IF NOT A STRING ! 11202: # ! 11203: sdup4: jsb gtpat # convert argument to pattern ! 11204: .long er_091 # dupl first argument is not string or pattern ! 11205: # ! 11206: # HERE TO DUPLICATE A PATTERN ARGUMENT ! 11207: # ! 11208: movl r9,-(sp) # store pattern on stack ! 11209: movl $ndnth,r9 # start off with null pattern ! 11210: tstl r7 # null pattern is result if dupfac=0 ! 11211: beqlu sdup6 ! 11212: movl r7,-(sp) # preserve loop count ! 11213: # ! 11214: # LOOP TO DUPLICATE BY SUCCESSIVE CONCATENATION ! 11215: # ! 11216: sdup5: movl r9,r10 # copy current value as right argumnt ! 11217: movl 4*1(sp),r9 # get a new copy of left ! 11218: jsb pconc # concatenate ! 11219: decl (sp) # count down ! 11220: tstl (sp) # loop ! 11221: bnequ sdup5 ! 11222: addl2 $4,sp # pop loop count ! 11223: # ! 11224: # HERE TO EXIT AFTER CONSTRUCTING PATTERN ! 11225: # ! 11226: sdup6: movl r9,(sp) # store result on stack ! 11227: jmp exits # exit with result on stack ! 11228: # ! 11229: # FAIL IF SECOND ARG IS OUT OF RANGE ! 11230: # ! 11231: sdup7: addl2 $4,sp # pop first argument ! 11232: jmp exfal # fail ! 11233: #page ! 11234: # ! 11235: # EJECT ! 11236: # ! 11237: s$ejc: # entry point ! 11238: jsb iofcb # call fcblk routine ! 11239: .long er_092 # eject argument is not a suitable name ! 11240: .long sejc1 # null argument ! 11241: jsb sysef # call eject file function ! 11242: .long er_093 # eject file does not exist ! 11243: .long er_094 # eject file does not permit page eject ! 11244: .long er_095 # eject caused non-recoverable output error ! 11245: jmp exnul # return null as result ! 11246: # ! 11247: # HERE TO EJECT STANDARD OUTPUT FILE ! 11248: # ! 11249: sejc1: jsb sysep # call routine to eject printer ! 11250: jmp exnul # exit with null result ! 11251: #page ! 11252: # ! 11253: # ENDFILE ! 11254: # ! 11255: s$enf: # entry point ! 11256: jsb iofcb # call fcblk routine ! 11257: .long er_096 # endfile argument is not a suitable name ! 11258: .long er_097 # endfile argument is null ! 11259: jsb sysen # call endfile routine ! 11260: .long er_098 # endfile file does not exist ! 11261: .long er_099 # endfile file does not permit endfile ! 11262: .long er_100 # endfile caused non-recoverable output error ! 11263: movl r10,r7 # remember vrblk ptr from iofcb call ! 11264: # ! 11265: # LOOP TO FIND TRTRF BLOCK ! 11266: # ! 11267: senf1: movl r10,r9 # copy pointer ! 11268: movl 4*trval(r9),r9 # chain along ! 11269: cmpl (r9),$b$trt # skip out if chain end ! 11270: beqlu 0f ! 11271: jmp exnul ! 11272: 0: ! 11273: cmpl 4*trtyp(r9),$trtfc # loop if not found ! 11274: bnequ senf1 ! 11275: movl 4*trval(r9),4*trval(r10) # remove trtrf ! 11276: movl 4*trtrf(r9),enfch# point to head of iochn ! 11277: movl 4*trfpt(r9),r8 # point to fcblk ! 11278: movl r7,r9 # filearg1 vrblk from iofcb ! 11279: jsb setvr # reset it ! 11280: movl $r$fcb,r10 # ptr to head of fcblk chain ! 11281: subl2 $4*num02,r10 # adjust ready to enter loop ! 11282: # ! 11283: # FIND FCBLK ! 11284: # ! 11285: senf2: movl r10,r9 # copy ptr ! 11286: movl 4*2(r10),r10 # get next link ! 11287: tstl r10 # stop if chain end ! 11288: beqlu senf4 ! 11289: cmpl 4*3(r10),r8 # jump if fcblk found ! 11290: beqlu senf3 ! 11291: jmp senf2 # loop ! 11292: # ! 11293: # REMOVE FCBLK ! 11294: # ! 11295: senf3: movl 4*2(r10),4*2(r9)# delete fcblk from chain ! 11296: # ! 11297: # LOOP WHICH DETACHES ALL VBLS ON IOCHN CHAIN ! 11298: # ! 11299: senf4: movl enfch,r10 # get chain head ! 11300: tstl r10 # finished if chain end ! 11301: bnequ 0f ! 11302: jmp exnul ! 11303: 0: ! 11304: movl 4*trtrf(r10),enfch # chain along ! 11305: movl 4*ionmo(r10),r6 # name offset ! 11306: movl 4*ionmb(r10),r10# name base ! 11307: jsb dtach # detach name ! 11308: jmp senf4 # loop till done ! 11309: #page ! 11310: # ! 11311: # EQ ! 11312: # ! 11313: s$eqf: # entry point ! 11314: jsb acomp # call arithmetic comparison routine ! 11315: .long er_101 # eq first argument is not numeric ! 11316: .long er_102 # eq second argument is not numeric ! 11317: .long exfal # fail if lt ! 11318: .long exnul # return null if eq ! 11319: .long exfal # fail if gt ! 11320: #page ! 11321: # ! 11322: # EVAL ! 11323: # ! 11324: s$evl: # entry point ! 11325: movl (sp)+,r9 # load argument ! 11326: jsb gtexp # convert to expression ! 11327: .long er_103 # eval argument is not expression ! 11328: movl (r3)+,r8 # load next code word ! 11329: cmpl r8,$ofne$ # jump if called by value ! 11330: bnequ sevl1 ! 11331: movl r3,r10 # copy code pointer ! 11332: movl (r10),r6 # get next code word ! 11333: cmpl r6,$ornm$ # by name unless expression ! 11334: bnequ sevl2 ! 11335: tstl 4*1(sp) # jump if by name ! 11336: bnequ sevl2 ! 11337: # ! 11338: # HERE IF CALLED BY VALUE ! 11339: # ! 11340: sevl1: clrl r7 # set flag for by value ! 11341: movl r8,-(sp) # save code word ! 11342: jsb evalx # evaluate expression by value ! 11343: .long exfal # fail if evaluation fails ! 11344: movl r9,r10 # copy result ! 11345: movl (sp),r9 # reload next code word ! 11346: movl r10,(sp) # stack result ! 11347: movl (r9),r11 # jump to execute next code word ! 11348: jmp (r11) ! 11349: # ! 11350: # HERE IF CALLED BY NAME ! 11351: # ! 11352: sevl2: movl $num01,r7 # set flag for by name ! 11353: jsb evalx # evaluate expression by name ! 11354: .long exfal # fail if evaluation fails ! 11355: jmp exnam # exit with name ! 11356: #page ! 11357: # ! 11358: # EXIT ! 11359: # ! 11360: s$ext: # entry point ! 11361: clrl r7 # clear amount of static shift ! 11362: jsb gbcol # compact memory by collecting ! 11363: jsb gtstg # convert arg to string ! 11364: .long er_104 # exit argument is not suitable integer or string ! 11365: movl r9,r10 # copy string ptr ! 11366: jsb gtint # check it is integer ! 11367: .long sext1 # skip if unconvertible ! 11368: clrl r10 # note it is integer ! 11369: movl 4*icval(r9),r5 # get integer arg ! 11370: movl r$fcb,r7 # get fcblk chain header ! 11371: # ! 11372: # MERGE TO CALL OSINT EXIT ROUTINE ! 11373: # ! 11374: sext1: movl $headv,r9 # point to v.v string ! 11375: jsb sysxi # call external routine ! 11376: .long er_105 # exit action not available in this implementation ! 11377: .long er_106 # exit action caused irrecoverable error ! 11378: tstl r5 # return if argument 0 ! 11379: bneq 0f ! 11380: jmp exnul ! 11381: 0: ! 11382: clrl gbcnt # resuming execution so reset ! 11383: tstl r5 # skip if positive ! 11384: bgtr sext2 ! 11385: mnegl r5,r5 # make positive ! 11386: # ! 11387: # CHECK FOR OPTION RESPECIFICATION ! 11388: # ! 11389: sext2: movl r5,r8 # get value in work reg ! 11390: cmpl r8,$num03 # skip if was 3 ! 11391: beqlu sext3 ! 11392: movl r8,-(sp) # save value ! 11393: clrl r8 # set to read options ! 11394: jsb prpar # read syspp options ! 11395: movl (sp)+,r8 # restore value ! 11396: # ! 11397: # DEAL WITH HEADER OPTION (FIDDLED BY PRPAR) ! 11398: # ! 11399: sext3: movl sp,headp # assume no headers ! 11400: cmpl r8,$num01 # skip if not 1 ! 11401: bnequ sext4 ! 11402: clrl headp # request header printing ! 11403: # ! 11404: # ALMOST READY TO RESUME RUNNING ! 11405: # ! 11406: sext4: jsb systm # get execution time start (sgd11) ! 11407: movl r5,timsx # save as initial time ! 11408: movl kvstc,r5 # reset to ensure ... ! 11409: movl r5,kvstl # ... correct execution stats ! 11410: jmp exnul # resume execution ! 11411: #page ! 11412: # ! 11413: # FIELD ! 11414: # ! 11415: s$fld: # entry point ! 11416: jsb gtsmi # get second argument (field number) ! 11417: .long er_107 # field second argument is not integer ! 11418: .long exfal # fail if out of range ! 11419: movl r9,r7 # else save integer value ! 11420: movl (sp)+,r9 # load first argument ! 11421: jsb gtnvr # point to vrblk ! 11422: .long sfld1 # jump (error) if not variable name ! 11423: movl 4*vrfnc(r9),r9 # else point to function block ! 11424: cmpl (r9),$b$dfc # error if not datatype function ! 11425: bnequ sfld1 ! 11426: # ! 11427: # HERE IF FIRST ARGUMENT IS A DATATYPE FUNCTION NAME ! 11428: # ! 11429: tstl r7 # fail if argument number is zero ! 11430: bnequ 0f ! 11431: jmp exfal ! 11432: 0: ! 11433: cmpl r7,4*fargs(r9) # fail if too large ! 11434: blequ 0f ! 11435: jmp exfal ! 11436: 0: ! 11437: moval 0[r7],r7 # else convert to byte offset ! 11438: addl2 r7,r9 # point to field name ! 11439: movl 4*dfflb(r9),r9 # load vrblk pointer ! 11440: jmp exvnm # exit to build nmblk ! 11441: # ! 11442: # HERE FOR BAD FIRST ARGUMENT ! 11443: # ! 11444: sfld1: jmp er_108 # field first argument is not datatype name ! 11445: #page ! 11446: # ! 11447: # FENCE ! 11448: # ! 11449: s$fnc: # entry point ! 11450: movl $p$fnc,r7 # set pcode for p$fnc ! 11451: clrl r9 # p0blk ! 11452: jsb pbild # build p$fnc node ! 11453: movl r9,r10 # save pointer to it ! 11454: movl (sp)+,r9 # get argument ! 11455: jsb gtpat # convert to pattern ! 11456: .long er_259 # fence argument is not pattern ! 11457: jsb pconc # concatenate to p$fnc node ! 11458: movl r9,r10 # save ptr to concatenated pattern ! 11459: movl $p$fna,r7 # set for p$fna pcode ! 11460: clrl r9 # p0blk ! 11461: jsb pbild # construct p$fna node ! 11462: movl r10,4*pthen(r9) # set pattern as pthen ! 11463: movl r9,-(sp) # set as result ! 11464: jmp exits # do next code word ! 11465: #page ! 11466: # ! 11467: # GE ! 11468: # ! 11469: s$gef: # entry point ! 11470: jsb acomp # call arithmetic comparison routine ! 11471: .long er_109 # ge first argument is not numeric ! 11472: .long er_110 # ge second argument is not numeric ! 11473: .long exfal # fail if lt ! 11474: .long exnul # return null if eq ! 11475: .long exnul # return null if gt ! 11476: #page ! 11477: # ! 11478: # GT ! 11479: # ! 11480: s$gtf: # entry point ! 11481: jsb acomp # call arithmetic comparison routine ! 11482: .long er_111 # gt first argument is not numeric ! 11483: .long er_112 # gt second argument is not numeric ! 11484: .long exfal # fail if lt ! 11485: .long exfal # fail if eq ! 11486: .long exnul # return null if gt ! 11487: #page ! 11488: # ! 11489: # HOST ! 11490: # ! 11491: s$hst: # entry point ! 11492: movl (sp)+,r9 # get third arg ! 11493: movl (sp)+,r10 # get second arg ! 11494: movl (sp)+,r6 # get first arg ! 11495: jsb syshs # enter syshs routine ! 11496: .long er_254 # erroneous argument for host ! 11497: .long er_255 # error during execution of host ! 11498: .long shst1 # store host string ! 11499: .long exnul # return null result ! 11500: .long exixr # return xr ! 11501: .long exfal # fail return ! 11502: # ! 11503: # RETURN HOST STRING ! 11504: # ! 11505: shst1: tstl r10 # null string if syshs uncooperative ! 11506: bnequ 0f ! 11507: jmp exnul ! 11508: 0: ! 11509: movl 4*sclen(r10),r6 # length ! 11510: clrl r7 # zero offset ! 11511: jsb sbstr # build copy of string ! 11512: movl r9,-(sp) # stack the result ! 11513: jmp exits # return result on stack ! 11514: #page ! 11515: # ! 11516: # IDENT ! 11517: # ! 11518: s$idn: # entry point ! 11519: movl (sp)+,r9 # load second argument ! 11520: movl (sp)+,r10 # load first argument ! 11521: jsb ident # call ident comparison routine ! 11522: .long exnul # return null if ident ! 11523: jmp exfal # fail if differ ! 11524: #page ! 11525: # ! 11526: # INPUT ! 11527: # ! 11528: s$inp: # entry point ! 11529: clrl r7 # input flag ! 11530: jsb ioput # call input/output assoc. routine ! 11531: .long er_113 # input third argument is not a string ! 11532: .long er_114 # inappropriate second argument for input ! 11533: .long er_115 # inappropriate first argument for input ! 11534: .long er_116 # inappropriate file specification for input ! 11535: .long exfal # fail if file does not exist ! 11536: .long er_117 # input file cannot be read ! 11537: jmp exnul # return null string ! 11538: #page ! 11539: # ! 11540: # INSERT ! 11541: # ! 11542: s$ins: # entry point ! 11543: movl (sp)+,r10 # get string arg ! 11544: jsb gtsmi # get replace length ! 11545: .long er_277 # insert third argument not integer ! 11546: .long exfal # fail if out of range ! 11547: movl r8,r7 # copy to proper reg ! 11548: jsb gtsmi # get replace position ! 11549: .long er_278 # insert second argument not integer ! 11550: .long exfal # fail if out of range ! 11551: tstl r8 # fail if zero ! 11552: bnequ 0f ! 11553: jmp exfal ! 11554: 0: ! 11555: decl r8 # decrement to get offset ! 11556: movl r8,r6 # put in proper register ! 11557: movl (sp)+,r9 # get buffer ! 11558: cmpl (r9),$b$bct # press on if type ok ! 11559: beqlu sins1 ! 11560: jmp er_279 # insert first argument not buffer ! 11561: # ! 11562: # HERE WHEN EVERYTHING LOADED UP ! 11563: # ! 11564: sins1: jsb insbf # call to insert ! 11565: .long er_280 # insert fourth argument not a string ! 11566: .long exfal # fail if out of range ! 11567: jmp exnul # else ok - exit with null ! 11568: #page ! 11569: # ! 11570: # INTEGER ! 11571: # ! 11572: s$int: # entry point ! 11573: movl (sp)+,r9 # load argument ! 11574: jsb gtnum # convert to numeric ! 11575: .long exfal # fail if non-numeric ! 11576: cmpl r6,$b$icl # return null if integer ! 11577: bnequ 0f ! 11578: jmp exnul ! 11579: 0: ! 11580: jmp exfal # fail if real ! 11581: #page ! 11582: # ! 11583: # ITEM ! 11584: # ! 11585: # ITEM DOES NOT PERMIT THE DIRECT (FAST) CALL SO THAT ! 11586: # WA CONTAINS THE ACTUAL NUMBER OF ARGUMENTS PASSED. ! 11587: # ! 11588: s$itm: # entry point ! 11589: # ! 11590: # DEAL WITH CASE OF NO ARGS ! 11591: # ! 11592: tstl r6 # jump if at least one arg ! 11593: bnequ sitm1 ! 11594: movl $nulls,-(sp) # else supply garbage null arg ! 11595: movl $num01,r6 # and fix argument count ! 11596: # ! 11597: # CHECK FOR NAME/VALUE CASES ! 11598: # ! 11599: sitm1: movl r3,r9 # get current code pointer ! 11600: movl (r9),r10 # load next code word ! 11601: decl r6 # get number of subscripts ! 11602: movl r6,r9 # copy for arref ! 11603: cmpl r10,$ofne$ # jump if called by name ! 11604: beqlu sitm2 ! 11605: # ! 11606: # HERE IF CALLED BY VALUE ! 11607: # ! 11608: clrl r7 # set code for call by value ! 11609: jmp arref # off to array reference routine ! 11610: # ! 11611: # HERE FOR CALL BY NAME ! 11612: # ! 11613: sitm2: movl sp,r7 # set code for call by name ! 11614: movl (r3)+,r6 # load and ignore ofne$ call ! 11615: jmp arref # off to array reference routine ! 11616: #page ! 11617: # ! 11618: # LE ! 11619: # ! 11620: s$lef: # entry point ! 11621: jsb acomp # call arithmetic comparison routine ! 11622: .long er_118 # le first argument is not numeric ! 11623: .long er_119 # le second argument is not numeric ! 11624: .long exnul # return null if lt ! 11625: .long exnul # return null if eq ! 11626: .long exfal # fail if gt ! 11627: #page ! 11628: # ! 11629: # LEN ! 11630: # ! 11631: s$len: # entry point ! 11632: movl $p$len,r7 # set pcode for integer arg case ! 11633: movl $p$lnd,r6 # set pcode for expr arg case ! 11634: jsb patin # call common routine to build node ! 11635: .long er_120 # len argument is not integer or expression ! 11636: .long er_121 # len argument is negative or too large ! 11637: jmp exixr # return pattern node ! 11638: #page ! 11639: # ! 11640: # LEQ ! 11641: # ! 11642: s$leq: # entry point ! 11643: jsb lcomp # call string comparison routine ! 11644: .long er_122 # leq first argument is not string ! 11645: .long er_123 # leq second argument is not string ! 11646: .long exfal # fail if llt ! 11647: .long exnul # return null if leq ! 11648: .long exfal # fail if lgt ! 11649: #page ! 11650: # ! 11651: # LGE ! 11652: # ! 11653: s$lge: # entry point ! 11654: jsb lcomp # call string comparison routine ! 11655: .long er_124 # lge first argument is not string ! 11656: .long er_125 # lge second argument is not string ! 11657: .long exfal # fail if llt ! 11658: .long exnul # return null if leq ! 11659: .long exnul # return null if lgt ! 11660: #page ! 11661: # ! 11662: # LGT ! 11663: # ! 11664: s$lgt: # entry point ! 11665: jsb lcomp # call string comparison routine ! 11666: .long er_126 # lgt first argument is not string ! 11667: .long er_127 # lgt second argument is not string ! 11668: .long exfal # fail if llt ! 11669: .long exfal # fail if leq ! 11670: .long exnul # return null if lgt ! 11671: #page ! 11672: # ! 11673: # LLE ! 11674: # ! 11675: s$lle: # entry point ! 11676: jsb lcomp # call string comparison routine ! 11677: .long er_128 # lle first argument is not string ! 11678: .long er_129 # lle second argument is not string ! 11679: .long exnul # return null if llt ! 11680: .long exnul # return null if leq ! 11681: .long exfal # fail if lgt ! 11682: #page ! 11683: # ! 11684: # LLT ! 11685: # ! 11686: s$llt: # entry point ! 11687: jsb lcomp # call string comparison routine ! 11688: .long er_130 # llt first argument is not string ! 11689: .long er_131 # llt second argument is not string ! 11690: .long exnul # return null if llt ! 11691: .long exfal # fail if leq ! 11692: .long exfal # fail if lgt ! 11693: #page ! 11694: # ! 11695: # LNE ! 11696: # ! 11697: s$lne: # entry point ! 11698: jsb lcomp # call string comparison routine ! 11699: .long er_132 # lne first argument is not string ! 11700: .long er_133 # lne second argument is not string ! 11701: .long exnul # return null if llt ! 11702: .long exfal # fail if leq ! 11703: .long exnul # return null if lgt ! 11704: #page ! 11705: # ! 11706: # LOCAL ! 11707: # ! 11708: s$loc: # entry point ! 11709: jsb gtsmi # get second argument (local number) ! 11710: .long er_134 # local second argument is not integer ! 11711: .long exfal # fail if out of range ! 11712: movl r9,r7 # save local number ! 11713: movl (sp)+,r9 # load first argument ! 11714: jsb gtnvr # point to vrblk ! 11715: .long sloc1 # jump if not variable name ! 11716: movl 4*vrfnc(r9),r9 # else load function pointer ! 11717: cmpl (r9),$b$pfc # jump if not program defined ! 11718: bnequ sloc1 ! 11719: # ! 11720: # HERE IF WE HAVE A PROGRAM DEFINED FUNCTION NAME ! 11721: # ! 11722: tstl r7 # fail if second arg is zero ! 11723: bnequ 0f ! 11724: jmp exfal ! 11725: 0: ! 11726: cmpl r7,4*pfnlo(r9) # or too large ! 11727: blequ 0f ! 11728: jmp exfal ! 11729: 0: ! 11730: addl2 4*fargs(r9),r7 # else adjust offset to include args ! 11731: moval 0[r7],r7 # convert to bytes ! 11732: addl2 r7,r9 # point to local pointer ! 11733: movl 4*pfagb(r9),r9 # load vrblk pointer ! 11734: jmp exvnm # exit building nmblk ! 11735: # ! 11736: # HERE IF FIRST ARGUMENT IS NO GOOD ! 11737: # ! 11738: sloc1: jmp er_135 # local first arg is not a program function name ! 11739: #page ! 11740: # ! 11741: # LOAD ! 11742: # ! 11743: s$lod: # entry point ! 11744: jsb gtstg # load library name ! 11745: .long er_136 # load second argument is not string ! 11746: movl r9,r10 # save library name ! 11747: jsb xscni # prepare to scan first argument ! 11748: .long er_137 # load first argument is not string ! 11749: .long er_138 # load first argument is null ! 11750: movl r10,-(sp) # stack library name ! 11751: movl $ch$pp,r8 # set delimiter one = left paren ! 11752: movl r8,r10 # set delimiter two = left paren ! 11753: jsb xscan # scan function name ! 11754: movl r9,-(sp) # save ptr to function name ! 11755: tstl r6 # jump if left paren found ! 11756: bnequ slod1 ! 11757: jmp er_139 # load first argument is missing a left paren ! 11758: # ! 11759: # HERE AFTER SUCCESSFULLY SCANNING FUNCTION NAME ! 11760: # ! 11761: slod1: jsb gtnvr # locate vrblk ! 11762: .long er_140 # load first argument has null function name ! 11763: movl r9,lodfn # save vrblk pointer ! 11764: clrl lodna # zero count of arguments ! 11765: # ! 11766: # LOOP TO SCAN ARGUMENT DATATYPE NAMES ! 11767: # ! 11768: slod2: movl $ch$rp,r8 # delimiter one is right paren ! 11769: movl $ch$cm,r10 # delimiter two is comma ! 11770: jsb xscan # scan next argument name ! 11771: incl lodna # bump argument count ! 11772: tstl r6 # jump if ok delimiter was found ! 11773: bnequ slod3 ! 11774: jmp er_141 # load first argument is missing a right paren ! 11775: #page ! 11776: # ! 11777: # LOAD (CONTINUED) ! 11778: # ! 11779: # COME HERE TO ANALYZE THE DATATYPE POINTER IN (XR). THIS ! 11780: # CODE IS USED BOTH FOR ARGUMENTS (WA=1,2) AND FOR THE ! 11781: # RESULT DATATYPE (WITH WA SET TO ZERO). ! 11782: # ! 11783: slod3: movl r9,-(sp) # stack datatype name pointer ! 11784: movl $num01,r7 # set string code in case ! 11785: movl $scstr,r10 # point to /string/ ! 11786: jsb ident # check for match ! 11787: .long slod4 # jump if match ! 11788: movl (sp),r9 # else reload name ! 11789: addl2 r7,r7 # set code for integer (2) ! 11790: movl $scint,r10 # point to /integer/ ! 11791: jsb ident # check for match ! 11792: .long slod4 # jump if match ! 11793: movl (sp),r9 # else reload string pointer ! 11794: incl r7 # set code for real (3) ! 11795: movl $screa,r10 # point to /real/ ! 11796: jsb ident # check for match ! 11797: .long slod4 # jump if match ! 11798: clrl r7 # else get code for no convert ! 11799: # ! 11800: # MERGE HERE WITH PROPER DATATYPE CODE IN WB ! 11801: # ! 11802: slod4: movl r7,(sp) # store code on stack ! 11803: cmpl r6,$num02 # loop back if arg stopped by comma ! 11804: beqlu slod2 ! 11805: tstl r6 # jump if that was the result type ! 11806: beqlu slod5 ! 11807: # ! 11808: # HERE WE SCAN OUT THE RESULT TYPE (ARG STOPPED BY ) ) ! 11809: # ! 11810: movl mxlen,r8 # set dummy (impossible) delimiter 1 ! 11811: movl r8,r10 # and delimiter two ! 11812: jsb xscan # scan result name ! 11813: clrl r6 # set code for processing result ! 11814: jmp slod3 # jump back to process result name ! 11815: #page ! 11816: # ! 11817: # LOAD (CONTINUED) ! 11818: # ! 11819: # HERE AFTER PROCESSING ALL ARGS AND RESULT ! 11820: # ! 11821: slod5: movl lodna,r6 # get number of arguments ! 11822: movl r6,r8 # copy for later ! 11823: moval 0[r6],r6 # convert length to bytes ! 11824: addl2 $4*efsi$,r6 # add space for standard fields ! 11825: jsb alloc # allocate efblk ! 11826: movl $b$efc,(r9) # set type word ! 11827: movl r8,4*fargs(r9) # set number of arguments ! 11828: clrl 4*efuse(r9) # set use count (dffnc will set to 1) ! 11829: clrl 4*efcod(r9) # zero code pointer for now ! 11830: movl (sp)+,4*efrsl(r9)# store result type code ! 11831: movl lodfn,4*efvar(r9)# store function vrblk pointer ! 11832: movl r6,4*eflen(r9) # store efblk length ! 11833: movl r9,r7 # save efblk pointer ! 11834: addl2 r6,r9 # point past end of efblk ! 11835: # set number of arguments for loop ! 11836: # ! 11837: # LOOP TO SET ARGUMENT TYPE CODES FROM STACK ! 11838: # ! 11839: slod6: movl (sp)+,-(r9) # store one type code from stack ! 11840: sobgtr r8,slod6 # loop till all stored ! 11841: # ! 11842: # NOW LOAD THE EXTERNAL FUNCTION AND PERFORM DEFINITION ! 11843: # ! 11844: movl (sp)+,r9 # load function string name ! 11845: movl (sp),r10 # load library name ! 11846: movl r7,(sp) # store efblk pointer ! 11847: jsb sysld # call function to load external func ! 11848: .long er_142 # load function does not exist ! 11849: .long er_143 # load function caused input error during load ! 11850: movl (sp)+,r10 # recall efblk pointer ! 11851: movl r9,4*efcod(r10) # store code pointer ! 11852: movl lodfn,r9 # point to vrblk for function ! 11853: jsb dffnc # perform function definition ! 11854: jmp exnul # return null result ! 11855: #page ! 11856: # ! 11857: # LPAD ! 11858: # ! 11859: s$lpd: # entry point ! 11860: jsb gtstg # get pad character ! 11861: .long er_144 # lpad third argument not a string ! 11862: movab cfp$f(r9),r9 # point to character (null is blank) ! 11863: movzbl (r9),r7 # load pad character ! 11864: jsb gtsmi # get pad length ! 11865: .long er_145 # lpad second argument is not integer ! 11866: .long slpd3 # skip if negative or large ! 11867: # ! 11868: # MERGE TO CHECK FIRST ARG ! 11869: # ! 11870: slpd1: jsb gtstg # get first argument (string to pad) ! 11871: .long er_146 # lpad first argument is not string ! 11872: cmpl r6,r8 # return 1st arg if too long to pad ! 11873: blssu 0f ! 11874: jmp exixr ! 11875: 0: ! 11876: movl r9,r10 # else move ptr to string to pad ! 11877: # ! 11878: # NOW WE ARE READY FOR THE PAD ! 11879: # ! 11880: # (XL) POINTER TO STRING TO PAD ! 11881: # (WB) PAD CHARACTER ! 11882: # (WC) LENGTH TO PAD STRING TO ! 11883: # ! 11884: movl r8,r6 # copy length ! 11885: jsb alocs # allocate scblk for new string ! 11886: movl r9,-(sp) # save as result ! 11887: movl 4*sclen(r10),r6 # load length of argument ! 11888: subl2 r6,r8 # calculate number of pad characters ! 11889: movab cfp$f(r9),r9 # point to chars in result string ! 11890: # set counter for pad loop ! 11891: # ! 11892: # LOOP TO PERFORM PAD ! 11893: # ! 11894: slpd2: movb r7,(r9)+ # store pad character, bump ptr ! 11895: sobgtr r8,slpd2 # loop till all pad chars stored ! 11896: #csc r9 # complete store characters ! 11897: # ! 11898: # NOW COPY STRING ! 11899: # ! 11900: tstl r6 # exit if null string ! 11901: bnequ 0f ! 11902: jmp exits ! 11903: 0: ! 11904: movab cfp$f(r10),r10 # else point to chars in argument ! 11905: jsb sbmvc # move characters to result string ! 11906: jmp exits # jump for next code word ! 11907: # ! 11908: # HERE IF 2ND ARG IS NEGATIVE OR LARGE ! 11909: # ! 11910: slpd3: clrl r8 # zero pad count ! 11911: jmp slpd1 # merge ! 11912: #page ! 11913: # ! 11914: # LT ! 11915: # ! 11916: s$ltf: # entry point ! 11917: jsb acomp # call arithmetic comparison routine ! 11918: .long er_147 # lt first argument is not numeric ! 11919: .long er_148 # lt second argument is not numeric ! 11920: .long exnul # return null if lt ! 11921: .long exfal # fail if eq ! 11922: .long exfal # fail if gt ! 11923: #page ! 11924: # ! 11925: # NE ! 11926: # ! 11927: s$nef: # entry point ! 11928: jsb acomp # call arithmetic comparison routine ! 11929: .long er_149 # ne first argument is not numeric ! 11930: .long er_150 # ne second argument is not numeric ! 11931: .long exnul # return null if lt ! 11932: .long exfal # fail if eq ! 11933: .long exnul # return null if gt ! 11934: #page ! 11935: # ! 11936: # NOTANY ! 11937: # ! 11938: s$nay: # entry point ! 11939: movl $p$nas,r7 # set pcode for single char arg ! 11940: movl $p$nay,r10 # pcode for multi-char arg ! 11941: movl $p$nad,r8 # set pcode for expr arg ! 11942: jsb patst # call common routine to build node ! 11943: .long er_151 # notany argument is not string or expression ! 11944: jmp exixr # jump for next code word ! 11945: #page ! 11946: # ! 11947: # OPSYN ! 11948: # ! 11949: s$ops: # entry point ! 11950: jsb gtsmi # load third argument ! 11951: .long er_152 # opsyn third argument is not integer ! 11952: .long er_153 # opsyn third argument is negative or too large ! 11953: movl r8,r7 # if ok, save third argumnet ! 11954: movl (sp)+,r9 # load second argument ! 11955: jsb gtnvr # locate variable block ! 11956: .long er_154 # opsyn second arg is not natural variable name ! 11957: movl 4*vrfnc(r9),r10 # if ok, load function block pointer ! 11958: tstl r7 # jump if operator opsyn case ! 11959: bnequ sops2 ! 11960: # ! 11961: # HERE FOR FUNCTION OPSYN (THIRD ARG ZERO) ! 11962: # ! 11963: movl (sp)+,r9 # load first argument ! 11964: jsb gtnvr # get vrblk pointer ! 11965: .long er_155 # opsyn first arg is not natural variable name ! 11966: # ! 11967: # MERGE HERE TO PERFORM FUNCTION DEFINITION ! 11968: # ! 11969: sops1: jsb dffnc # call function definer ! 11970: jmp exnul # exit with null result ! 11971: # ! 11972: # HERE FOR OPERATOR OPSYN (THIRD ARG NON-ZERO) ! 11973: # ! 11974: sops2: jsb gtstg # get operator name ! 11975: .long sops5 # jump if not string ! 11976: cmpl r6,$num01 # error if not one char long ! 11977: bnequ sops5 ! 11978: movab cfp$f(r9),r9 # else point to character ! 11979: movzbl (r9),r8 # load character name ! 11980: #page ! 11981: # ! 11982: # OPSYN (CONTINUED) ! 11983: # ! 11984: # NOW SET TO SEARCH FOR MATCHING UNARY OR BINARY OPERATOR ! 11985: # NAME AS APPROPRIATE. NOTE THAT THERE ARE =OPBUN UNDEFINED ! 11986: # BINARY OPERATORS AND =OPUUN UNDEFINED UNARY OPERATORS. ! 11987: # ! 11988: movl $r$uub,r6 # point to unop pointers in case ! 11989: movl $opnsu,r9 # point to names of unary operators ! 11990: addl2 $opbun,r7 # add no. of undefined binary ops ! 11991: cmpl r7,$opuun # jump if unop (third arg was 1) ! 11992: beqlu sops3 ! 11993: movl $r$uba,r6 # else point to binary operator ptrs ! 11994: movl $opsnb,r9 # point to names of binary operators ! 11995: movl $opbun,r7 # set number of undefined binops ! 11996: # ! 11997: # MERGE HERE TO CHECK LIST (WB = NUMBER TO CHECK) ! 11998: # ! 11999: sops3: # set counter to control loop ! 12000: # ! 12001: # LOOP TO SEARCH FOR NAME MATCH ! 12002: # ! 12003: sops4: cmpl r8,(r9) # jump if names match ! 12004: beqlu sops6 ! 12005: addl2 $4,r6 # else push pointer to function ptr ! 12006: addl2 $4,r9 # bump pointer ! 12007: sobgtr r7,sops4 # loop back till all checked ! 12008: # ! 12009: # HERE IF BAD OPERATOR NAME ! 12010: # ! 12011: sops5: jmp er_156 # opsyn first arg is not correct operator name ! 12012: # ! 12013: # COME HERE ON FINDING A MATCH IN THE OPERATOR NAME TABLE ! 12014: # ! 12015: sops6: movl r6,r9 # copy pointer to function block ptr ! 12016: subl2 $4*vrfnc,r9 # make it look like dummy vrblk ! 12017: jmp sops1 # merge back to define operator ! 12018: #page ! 12019: # ! 12020: # OUTPUT ! 12021: # ! 12022: s$oup: # entry point ! 12023: movl $num03,r7 # output flag ! 12024: jsb ioput # call input/output assoc. routine ! 12025: .long er_157 # output third argument is not a string ! 12026: .long er_158 # inappropriate second argument for output ! 12027: .long er_159 # inappropriate first argument for output ! 12028: .long er_160 # inappropriate file specification for output ! 12029: .long exfal # fail if file does not exist ! 12030: .long er_161 # output file cannot be written to ! 12031: jmp exnul # return null string ! 12032: #page ! 12033: # ! 12034: # POS ! 12035: # ! 12036: s$pos: # entry point ! 12037: movl $p$pos,r7 # set pcode for integer arg case ! 12038: movl $p$psd,r6 # set pcode for expression arg case ! 12039: jsb patin # call common routine to build node ! 12040: .long er_162 # pos argument is not integer or expression ! 12041: .long er_163 # pos argument is negative or too large ! 12042: jmp exixr # return pattern node ! 12043: #page ! 12044: # ! 12045: # PROTOTYPE ! 12046: # ! 12047: s$pro: # entry point ! 12048: movl (sp)+,r9 # load argument ! 12049: movl 4*tblen(r9),r7 # length if table, vector (=vclen) ! 12050: ashl $-2,r7,r7 # convert to words ! 12051: movl (r9),r6 # load type word of argument block ! 12052: cmpl r6,$b$art # jump if array ! 12053: beqlu spro4 ! 12054: cmpl r6,$b$tbt # jump if table ! 12055: beqlu spro1 ! 12056: cmpl r6,$b$vct # jump if vector ! 12057: beqlu spro3 ! 12058: cmpl r6,$b$bct # jump if buffer ! 12059: beqlu spr05 ! 12060: jmp er_164 # prototype argument is not valid object ! 12061: # ! 12062: # HERE FOR TABLE ! 12063: # ! 12064: spro1: subl2 $tbsi$,r7 # subtract standard fields ! 12065: # ! 12066: # MERGE FOR VECTOR ! 12067: # ! 12068: spro2: movl r7,r5 # convert to integer ! 12069: jmp exint # exit with integer result ! 12070: # ! 12071: # HERE FOR VECTOR ! 12072: # ! 12073: spro3: subl2 $vcsi$,r7 # subtract standard fields ! 12074: jmp spro2 # merge ! 12075: # ! 12076: # HERE FOR ARRAY ! 12077: # ! 12078: spro4: addl2 4*arofs(r9),r9 # point to prototype field ! 12079: movl (r9),r9 # load prototype ! 12080: jmp exixr # return prototype as result ! 12081: # ! 12082: # HERE FOR BUFFER ! 12083: # ! 12084: spr05: movl 4*bcbuf(r9),r9 # point to bfblk ! 12085: movl 4*bfalc(r9),r5 # load allocated length ! 12086: jmp exint # exit with integer allocation ! 12087: #page ! 12088: # ! 12089: # REMDR ! 12090: # ! 12091: s$rmd: # entry point ! 12092: clrl r7 # set positive flag ! 12093: movl (sp),r9 # load second argument ! 12094: jsb gtint # convert to integer ! 12095: .long er_165 # remdr second argument is not integer ! 12096: jsb arith # convert args ! 12097: .long srm01 # first arg not integer ! 12098: .long invalid$ # second arg checked above ! 12099: .long srm01 # first arg real ! 12100: movl 4*icval(r9),r5 # load left argument value ! 12101: ashq $-32,r4,r4 # get remainder ! 12102: ediv 4*icval(r10),r4,r11,r5 ! 12103: bvs 0f ! 12104: jmp exint ! 12105: 0: ! 12106: jmp er_167 # remdr caused integer overflow ! 12107: # ! 12108: # FAIL FIRST ARGUMENT ! 12109: # ! 12110: srm01: jmp er_166 # remdr first argument is not integer ! 12111: #page ! 12112: # ! 12113: # REPLACE ! 12114: # ! 12115: # THE ACTUAL REPLACE OPERATION USES AN SCBLK WHOSE CFP$A ! 12116: # CHARS CONTAIN THE TRANSLATED VERSIONS OF ALL THE CHARS. ! 12117: # THE TABLE POINTER IS REMEMBERED FROM CALL TO CALL AND ! 12118: # THE TABLE IS ONLY BUILT WHEN THE ARGUMENTS CHANGE. ! 12119: # ! 12120: s$rpl: # entry point ! 12121: jsb gtstg # load third argument as string ! 12122: .long er_168 # replace third argument is not string ! 12123: movl r9,r10 # save third arg ptr ! 12124: jsb gtstg # get second argument ! 12125: .long er_169 # replace second argument is not string ! 12126: # ! 12127: # CHECK TO SEE IF THIS IS THE SAME TABLE AS LAST TIME ! 12128: # ! 12129: cmpl r9,r$ra2 # jump if 2nd argument different ! 12130: bnequ srpl1 ! 12131: cmpl r10,r$ra3 # jump if args same as last time ! 12132: bnequ 0f ! 12133: jmp srpl4 ! 12134: 0: ! 12135: # ! 12136: # HERE WE BUILD A NEW REPLACE TABLE (NOTE WA = 2ND ARG LEN) ! 12137: # ! 12138: srpl1: movl 4*sclen(r10),r7 # load 3rd argument length ! 12139: cmpl r6,r7 # jump if arguments not same length ! 12140: beqlu 0f ! 12141: jmp srpl5 ! 12142: 0: ! 12143: tstl r7 # jump if null 2nd argument ! 12144: bnequ 0f ! 12145: jmp srpl5 ! 12146: 0: ! 12147: movl r10,r$ra3 # save third arg for next time in ! 12148: movl r9,r$ra2 # save second arg for next time in ! 12149: movl kvalp,r10 # point to alphabet string ! 12150: movl 4*sclen(r10),r6 # load alphabet scblk length ! 12151: movl r$rpt,r9 # point to current table (if any) ! 12152: tstl r9 # jump if we already have a table ! 12153: bnequ srpl2 ! 12154: # ! 12155: # HERE WE ALLOCATE A NEW TABLE ! 12156: # ! 12157: jsb alocs # allocate new table ! 12158: movl r8,r6 # keep scblk length ! 12159: movl r9,r$rpt # save table pointer for next time ! 12160: # ! 12161: # MERGE HERE WITH POINTER TO NEW TABLE BLOCK IN (XR) ! 12162: # ! 12163: srpl2: movab 3+(4*scsi$)(r6),r6 # compute length of scblk ! 12164: bicl2 $3,r6 ! 12165: jsb sbmvw # copy to get initial table values ! 12166: #page ! 12167: # ! 12168: # REPLACE (CONTINUED) ! 12169: # ! 12170: # NOW WE MUST PLUG SELECTED ENTRIES AS REQUIRED. NOTE THAT ! 12171: # WE ARE SHORT OF INDEX REGISTERS FOR THE FOLLOWING LOOP. ! 12172: # HENCE THE NEED TO REPEATEDLY RE-INITIALISE CHAR PTR XL ! 12173: # ! 12174: movl r$ra2,r10 # point to second argument ! 12175: # number of chars to plug ! 12176: clrl r8 # zero char offset ! 12177: movl r$ra3,r9 # point to 3rd arg ! 12178: movab cfp$f(r9),r9 # get char ptr for 3rd arg ! 12179: # ! 12180: # LOOP TO PLUG CHARS ! 12181: # ! 12182: srpl3: movl r$ra2,r10 # point to 2nd arg ! 12183: movab cfp$f(r10)[r8],r10 # point to next char ! 12184: incl r8 # increment offset ! 12185: movzbl (r10),r6 # get next char ! 12186: movl r$rpt,r10 # point to translate table ! 12187: movab cfp$f(r10)[r6],r10 # convert char to offset into table ! 12188: movzbl (r9)+,r6 # get translated char ! 12189: movb r6,(r10) # store in table ! 12190: #csc r10 # complete store characters ! 12191: sobgtr r7,srpl3 # loop till done ! 12192: #page ! 12193: # ! 12194: # REPLACE (CONTINUED) ! 12195: # ! 12196: # HERE TO PERFORM TRANSLATE ! 12197: # ! 12198: srpl4: jsb gtstg # get first argument ! 12199: .long er_170 # replace first argument is not string ! 12200: tstl r6 # return null if null argument ! 12201: bnequ 0f ! 12202: jmp exnul ! 12203: 0: ! 12204: movl r9,r10 # copy pointer ! 12205: movl r6,r8 # save length ! 12206: movab 3+(4*schar)(r6),r6 # get scblk length ! 12207: bicl2 $3,r6 ! 12208: jsb alloc # allocate space for copy ! 12209: movl r9,r7 # save address of copy ! 12210: jsb sbmvw # move scblk contents to copy ! 12211: movl r$rpt,r9 # point to replace table ! 12212: movab cfp$f(r9),r9 # point to chars of table ! 12213: movl r7,r10 # point to string to translate ! 12214: movab cfp$f(r10),r10 # point to chars of string ! 12215: movl r8,r6 # set number of chars to translate ! 12216: jsb sbtrc # perform translation ! 12217: movl r7,-(sp) # stack new string as result ! 12218: jmp exits # return with result on stack ! 12219: # ! 12220: # ERROR POINT ! 12221: # ! 12222: srpl5: jmp er_171 # null or unequally long 2nd, 3rd args to replace ! 12223: #page ! 12224: # ! 12225: # REWIND ! 12226: # ! 12227: s$rew: # entry point ! 12228: jsb iofcb # call fcblk routine ! 12229: .long er_172 # rewind argument is not a suitable name ! 12230: .long er_173 # rewind argument is null ! 12231: jsb sysrw # call system rewind function ! 12232: .long er_174 # rewind file does not exist ! 12233: .long er_175 # rewind file does not permit rewind ! 12234: .long er_176 # rewind caused non-recoverable error ! 12235: jmp exnul # exit with null result if no error ! 12236: #page ! 12237: # ! 12238: # REVERSE ! 12239: # ! 12240: s$rvs: # entry point ! 12241: jsb gtstg # load string argument ! 12242: .long er_177 # reverse argument is not string ! 12243: tstl r6 # return argument if null ! 12244: bnequ 0f ! 12245: jmp exixr ! 12246: 0: ! 12247: movl r9,r10 # else save pointer to string arg ! 12248: jsb alocs # allocate space for new scblk ! 12249: movl r9,-(sp) # store scblk ptr on stack as result ! 12250: movab cfp$f(r9),r9 # prepare to store in new scblk ! 12251: movab cfp$f(r10)[r8],r10 # point past last char in argument ! 12252: # set loop counter ! 12253: # ! 12254: # LOOP TO MOVE CHARS IN REVERSE ORDER ! 12255: # ! 12256: srvs1: movzbl -(r10),r7 # load next char from argument ! 12257: movb r7,(r9)+ # store in result ! 12258: sobgtr r8,srvs1 # loop till all moved ! 12259: #csc r9 # complete store characters ! 12260: jmp exits # and then jump for next code word ! 12261: #page ! 12262: # ! 12263: # RPAD ! 12264: # ! 12265: s$rpd: # entry point ! 12266: jsb gtstg # get pad character ! 12267: .long er_178 # rpad third argument is not string ! 12268: movab cfp$f(r9),r9 # point to character (null is blank) ! 12269: movzbl (r9),r7 # load pad character ! 12270: jsb gtsmi # get pad length ! 12271: .long er_179 # rpad second argument is not integer ! 12272: .long srpd3 # skip if negative or large ! 12273: # ! 12274: # MERGE TO CHECK FIRST ARG. ! 12275: # ! 12276: srpd1: jsb gtstg # get first argument (string to pad) ! 12277: .long er_180 # rpad first argument is not string ! 12278: cmpl r6,r8 # return 1st arg if too long to pad ! 12279: blssu 0f ! 12280: jmp exixr ! 12281: 0: ! 12282: movl r9,r10 # else move ptr to string to pad ! 12283: # ! 12284: # NOW WE ARE READY FOR THE PAD ! 12285: # ! 12286: # (XL) POINTER TO STRING TO PAD ! 12287: # (WB) PAD CHARACTER ! 12288: # (WC) LENGTH TO PAD STRING TO ! 12289: # ! 12290: movl r8,r6 # copy length ! 12291: jsb alocs # allocate scblk for new string ! 12292: movl r9,-(sp) # save as result ! 12293: movl 4*sclen(r10),r6 # load length of argument ! 12294: subl2 r6,r8 # calculate number of pad characters ! 12295: movab cfp$f(r9),r9 # point to chars in result string ! 12296: # set counter for pad loop ! 12297: # ! 12298: # COPY ARGUMENT STRING ! 12299: # ! 12300: tstl r6 # jump if argument is null ! 12301: beqlu srpd2 ! 12302: movab cfp$f(r10),r10 # else point to argument chars ! 12303: jsb sbmvc # move characters to result string ! 12304: # ! 12305: # LOOP TO SUPPLY PAD CHARACTERS ! 12306: # ! 12307: srpd2: movb r7,(r9)+ # store pad character, bump ptr ! 12308: sobgtr r8,srpd2 # loop till all pad chars stored ! 12309: #csc r9 # complete character storing ! 12310: jmp exits # and exit for next word ! 12311: # ! 12312: # HERE IF 2ND ARG IS NEGATIVE OR LARGE ! 12313: # ! 12314: srpd3: clrl r8 # zero pad count ! 12315: jmp srpd1 # merge ! 12316: #page ! 12317: # ! 12318: # RTAB ! 12319: # ! 12320: s$rtb: # entry point ! 12321: movl $p$rtb,r7 # set pcode for integer arg case ! 12322: movl $p$rtd,r6 # set pcode for expression arg case ! 12323: jsb patin # call common routine to build node ! 12324: .long er_181 # rtab argument is not integer or expression ! 12325: .long er_182 # rtab argument is negative or too large ! 12326: jmp exixr # return pattern node ! 12327: #page ! 12328: # ! 12329: # SET ! 12330: # ! 12331: s$set: # entry point ! 12332: movl (sp)+,r$io2 # save third arg ! 12333: movl (sp)+,r$io1 # save second arg ! 12334: jsb iofcb # call fcblk routine ! 12335: .long er_291 # set first argument is not a suitable name ! 12336: .long er_292 # set first argument is null ! 12337: movl r$io1,r7 # load second arg ! 12338: movl r$io2,r8 # load third arg ! 12339: jsb sysst # call system set routine ! 12340: .long er_293 # inappropriate second argument to set ! 12341: .long er_294 # inappropriate third argument to set ! 12342: .long er_295 # set file does not exist ! 12343: .long er_296 # set file does not permit setting file pointer ! 12344: .long er_297 # set caused non-recoverable i/o error ! 12345: jmp exnul # otherwisew return null ! 12346: #page ! 12347: # ! 12348: # TAB ! 12349: # ! 12350: s$tab: # entry point ! 12351: movl $p$tab,r7 # set pcode for integer arg case ! 12352: movl $p$tbd,r6 # set pcode for expression arg case ! 12353: jsb patin # call common routine to build node ! 12354: .long er_183 # tab argument is not integer or expression ! 12355: .long er_184 # tab argument is negative or too large ! 12356: jmp exixr # return pattern node ! 12357: #page ! 12358: # ! 12359: # RPOS ! 12360: # ! 12361: s$rps: # entry point ! 12362: movl $p$rps,r7 # set pcode for integer arg case ! 12363: movl $p$rpd,r6 # set pcode for expression arg case ! 12364: jsb patin # call common routine to build node ! 12365: .long er_185 # rpos argument is not integer or expression ! 12366: .long er_186 # rpos argument is negative or too large ! 12367: jmp exixr # return pattern node ! 12368: #page ! 12369: # ! 12370: # RSORT ! 12371: # ! 12372: s$rsr: # entry point ! 12373: movl sp,r6 # mark as rsort ! 12374: jsb sorta # call sort routine ! 12375: jmp exsid # return, setting idval ! 12376: #page ! 12377: # ! 12378: # SETEXIT ! 12379: # ! 12380: s$stx: # entry point ! 12381: movl (sp)+,r9 # load argument ! 12382: movl stxvr,r6 # load old vrblk pointer ! 12383: clrl r10 # load zero in case null arg ! 12384: cmpl r9,$nulls # jump if null argument (reset call) ! 12385: beqlu sstx1 ! 12386: jsb gtnvr # else get specified vrblk ! 12387: .long sstx2 # jump if not natural variable ! 12388: movl 4*vrlbl(r9),r10 # else load label ! 12389: cmpl r10,$stndl # jump if label is not defined ! 12390: beqlu sstx2 ! 12391: cmpl (r10),$b$trt # jump if not trapped ! 12392: bnequ sstx1 ! 12393: movl 4*trlbl(r10),r10# else load ptr to real label code ! 12394: # ! 12395: # HERE TO SET/RESET SETEXIT TRAP ! 12396: # ! 12397: sstx1: movl r9,stxvr # store new vrblk pointer (or null) ! 12398: movl r10,r$sxc # store new code ptr (or zero) ! 12399: cmpl r6,$nulls # return null if null result ! 12400: bnequ 0f ! 12401: jmp exnul ! 12402: 0: ! 12403: movl r6,r9 # else copy vrblk pointer ! 12404: jmp exvnm # and return building nmblk ! 12405: # ! 12406: # HERE IF BAD ARGUMENT ! 12407: # ! 12408: sstx2: jmp er_187 # setexit argument is not label name or null ! 12409: #page ! 12410: # ! 12411: # SORT ! 12412: # ! 12413: s$srt: # entry point ! 12414: clrl r6 # mark as sort ! 12415: jsb sorta # call sort routine ! 12416: jmp exsid # return, setting idval ! 12417: #page ! 12418: # ! 12419: # SPAN ! 12420: # ! 12421: s$spn: # entry point ! 12422: movl $p$sps,r7 # set pcode for single char arg ! 12423: movl $p$spn,r10 # set pcode for multi-char arg ! 12424: movl $p$spd,r8 # set pcode for expression arg ! 12425: jsb patst # call common routine to build node ! 12426: .long er_188 # span argument is not string or expression ! 12427: jmp exixr # jump for next code word ! 12428: #page ! 12429: # ! 12430: # SIZE ! 12431: # ! 12432: s$si$: # entry point ! 12433: movl (sp),r9 # load argument ! 12434: cmpl (r9),$b$bct # branch if not buffer ! 12435: bnequ ssi$1 ! 12436: addl2 $4,sp # else pop argument ! 12437: movl 4*bclen(r9),r5 # load defined length ! 12438: jmp exint # exit with integer ! 12439: # ! 12440: # HERE IF NOT BUFFER ! 12441: # ! 12442: ssi$1: jsb gtstg # load string argument ! 12443: .long er_189 # size argument is not string ! 12444: movl r6,r5 # load length as integer ! 12445: jmp exint # exit with integer result ! 12446: #page ! 12447: # ! 12448: # STOPTR ! 12449: # ! 12450: s$stt: # entry point ! 12451: clrl r10 # indicate stoptr case ! 12452: jsb trace # call trace procedure ! 12453: .long er_190 # stoptr first argument is not appropriate name ! 12454: .long er_191 # stoptr second argument is not trace type ! 12455: jmp exnul # return null ! 12456: #page ! 12457: # ! 12458: # SUBSTR ! 12459: # ! 12460: s$sub: # entry point ! 12461: jsb gtsmi # load third argument ! 12462: .long er_192 # substr third argument is not integer ! 12463: .long exfal # jump if negative or too large ! 12464: movl r9,sbssv # save third argument ! 12465: jsb gtsmi # load second argument ! 12466: .long er_193 # substr second argument is not integer ! 12467: .long exfal # jump if out of range ! 12468: movl r9,r7 # save second argument ! 12469: tstl r7 # jump if second argument zero ! 12470: bnequ 0f ! 12471: jmp exfal ! 12472: 0: ! 12473: decl r7 # else decrement for ones origin ! 12474: movl (sp),r10 # get first arg ptr ! 12475: cmpl (r10),$b$bct # branch if not buffer ! 12476: bnequ ssuba ! 12477: movl 4*bcbuf(r10),r9 # get bfblk ptr ! 12478: movl 4*bclen(r10),r6 # get length ! 12479: jmp ssubb # merge ! 12480: # ! 12481: # HERE IF NOT BUFFER TO GET STRING ! 12482: # ! 12483: ssuba: jsb gtstg # load first argument ! 12484: .long er_194 # substr first argument is not string ! 12485: # ! 12486: # MERGE WITH BFBLK OR SCBLK PTR IN XR. WA HAS LENGTH ! 12487: # ! 12488: ssubb: movl sbssv,r8 # reload third argument ! 12489: tstl r8 # skip if third arg given ! 12490: bnequ ssub1 ! 12491: movl r6,r8 # else get string length ! 12492: cmpl r7,r8 # fail if improper ! 12493: blequ 0f ! 12494: jmp exfal ! 12495: 0: ! 12496: subl2 r7,r8 # reduce by offset to start ! 12497: # ! 12498: # MERGE ! 12499: # ! 12500: ssub1: movl r6,r10 # save string length ! 12501: movl r8,r6 # set length of substring ! 12502: addl2 r7,r8 # add 2nd arg to 3rd arg ! 12503: cmpl r8,r10 # jump if improper substring ! 12504: blequ 0f ! 12505: jmp exfal ! 12506: 0: ! 12507: movl r9,r10 # copy pointer to first arg ! 12508: jsb sbstr # build substring ! 12509: jmp exixr # and jump for next code word ! 12510: #page ! 12511: # ! 12512: # TABLE ! 12513: # ! 12514: s$tbl: # entry point ! 12515: movl (sp)+,r10 # get initial lookup value ! 12516: addl2 $4,sp # pop second argument ! 12517: jsb gtsmi # load argument ! 12518: .long er_195 # table argument is not integer ! 12519: .long er_196 # table argument is out of range ! 12520: tstl r8 # jump if non-zero ! 12521: bnequ stbl1 ! 12522: movl $tbnbk,r8 # else supply default value ! 12523: # ! 12524: # MERGE HERE WITH NUMBER OF HEADERS IN WA ! 12525: # ! 12526: stbl1: movl r8,r6 # copy number of headers ! 12527: addl2 $tbsi$,r6 # adjust for standard fields ! 12528: moval 0[r6],r6 # convert length to bytes ! 12529: jsb alloc # allocate space for tbblk ! 12530: movl r9,r7 # copy pointer to tbblk ! 12531: movl $b$tbt,(r9)+ # store type word ! 12532: clrl (r9)+ # zero id for the moment ! 12533: movl r6,(r9)+ # store length (tblen) ! 12534: movl r10,(r9)+ # store initial lookup value ! 12535: # set loop counter (num headers) ! 12536: # ! 12537: # LOOP TO INITIALIZE ALL BUCKET POINTERS ! 12538: # ! 12539: stbl2: movl r7,(r9)+ # store tbblk ptr in bucket header ! 12540: sobgtr r8,stbl2 # loop till all stored ! 12541: movl r7,r9 # recall pointer to tbblk ! 12542: jmp exsid # exit setting idval ! 12543: #page ! 12544: # ! 12545: # TIME ! 12546: # ! 12547: s$tim: # entry point ! 12548: jsb systm # get timer value ! 12549: subl2 timsx,r5 # subtract starting time ! 12550: jmp exint # exit with integer value ! 12551: #page ! 12552: # ! 12553: # TRACE ! 12554: # ! 12555: s$tra: # entry point ! 12556: cmpl 4*3(sp),$nulls # jump if first argument is null ! 12557: beqlu str03 ! 12558: movl (sp)+,r9 # load fourth argument ! 12559: clrl r10 # tentatively set zero pointer ! 12560: cmpl r9,$nulls # jump if 4th argument is null ! 12561: beqlu str02 ! 12562: jsb gtnvr # else point to vrblk ! 12563: .long str01 # jump if not variable name ! 12564: movl 4*vrfnc(r9),r10 # else load function pointer ! 12565: cmpl r10,$stndf # jump if function is defined ! 12566: bnequ str02 ! 12567: # ! 12568: # HERE FOR BAD FOURTH ARGUMENT ! 12569: # ! 12570: str01: jmp er_197 # trace fourth arg is not function name or null ! 12571: # ! 12572: # HERE WITH FUNCTION POINTER IN XL ! 12573: # ! 12574: str02: movl (sp)+,r9 # load third argument (tag) ! 12575: clrl r7 # set zero as trtyp value for now ! 12576: jsb trbld # build trblk for trace call ! 12577: movl r9,r10 # move trblk pointer for trace ! 12578: jsb trace # call trace procedure ! 12579: .long er_198 # trace first argument is not appropriate name ! 12580: .long er_199 # trace second argument is not trace type ! 12581: jmp exnul # return null ! 12582: # ! 12583: # HERE TO CALL SYSTEM TRACE TOGGLE ROUTINE ! 12584: # ! 12585: str03: jsb systt # call it ! 12586: addl2 $4*num04,sp # pop trace arguments ! 12587: jmp exnul # return ! 12588: #page ! 12589: # ! 12590: # TRIM ! 12591: # ! 12592: s$trm: # entry point ! 12593: jsb gtstg # load argument as string ! 12594: .long er_200 # trim argument is not string ! 12595: tstl r6 # return null if argument is null ! 12596: bnequ 0f ! 12597: jmp exnul ! 12598: 0: ! 12599: movl r9,r10 # copy string pointer ! 12600: movab 3+(4*schar)(r6),r6 # get block length ! 12601: bicl2 $3,r6 ! 12602: jsb alloc # allocate copy same size ! 12603: movl r9,r7 # save pointer to copy ! 12604: jsb sbmvw # copy old string block to new ! 12605: movl r7,r9 # restore ptr to new block ! 12606: jsb trimr # trim blanks (wb is non-zero) ! 12607: jmp exixr # exit with result in xr ! 12608: #page ! 12609: # ! 12610: # UNLOAD ! 12611: # ! 12612: s$unl: # entry point ! 12613: movl (sp)+,r9 # load argument ! 12614: jsb gtnvr # point to vrblk ! 12615: .long er_201 # unload argument is not natural variable name ! 12616: movl $stndf,r10 # get ptr to undefined function ! 12617: jsb dffnc # undefine named function ! 12618: jmp exnul # return null as result ! 12619: #title s p i t b o l -- utility procedures ! 12620: # ! 12621: # THE FOLLOWING SECTION CONTAINS PROCEDURES WHICH ARE ! 12622: # USED FOR VARIOUS PURPOSES THROUGHOUT THE SYSTEM. ! 12623: # ! 12624: # EACH PROCEDURE IS PRECEDED BY A DESCRIPTION OF THE ! 12625: # CALLING SEQUENCE. USUALLY THE ARGUMENTS ARE IN REGISTERS ! 12626: # BUT ARGUMENTS CAN ALSO OCCUR ON THE STACK AND AS ! 12627: # PARAMETERS ASSEMBLED AFTER THE JSR INSTRUCTION. ! 12628: # ! 12629: # THE FOLLOWING CONSIDERATIONS APPLY TO THESE DESCRIPTIONS. ! 12630: # ! 12631: # 1) THE STACK POINTER (XS) IS NOT CHANGED UNLESS THE ! 12632: # CHANGE IS EXPLICITLY DOCUMENTED IN THE CALL. ! 12633: # ! 12634: # 2) REGISTERS WHOSE ENTRY VALUES ARE NOT MENTIONED ! 12635: # MAY CONTAIN ANY VALUE EXCEPT THAT XL,XR MAY ONLY ! 12636: # CONTAIN PROPER (COLLECTABLE) POINTER VALUES. ! 12637: # THIS CONDITION ON XR MEANS THAT THE CALLED ROUTINE ! 12638: # MAY IF IT CHOOSES PRESERVE XR BY STACKING. ! 12639: # ! 12640: # 3) REGISTERS NOT MENTIONED ON EXIT CONTAIN THE SAME ! 12641: # VALUES AS THEY DID ON ENTRY EXCEPT THAT VALUES IN ! 12642: # XR,XL MAY HAVE BEEN RELOCATED BY THE COLLECTOR. ! 12643: # ! 12644: # 4) REGISTERS WHICH ARE DESTROYED ON EXIT MAY CONTAIN ! 12645: # ANY VALUE EXCEPT THAT VALUES IN XL,XR ARE PROPER ! 12646: # (COLLECTABLE) POINTERS. ! 12647: # ! 12648: # 5) THE CODE POINTER REGISTER POINTS TO THE CURRENT ! 12649: # CODE LOCATION ON ENTRY AND IS UNCHANGED ON EXIT. ! 12650: # ! 12651: # IN THE ABOVE DESCRIPTION, A COLLECTABLE POINTER IS ONE ! 12652: # WHICH EITHER POINTS OUTSIDE THE DYNAMIC REGION OR ! 12653: # POINTS TO THE START OF A BLOCK IN THE DYNAMIC REGION. ! 12654: # ! 12655: # IN THOSE CASES WHERE THE CALLING SEQUENCE CONTAINS ! 12656: # PARAMETERS WHICH ARE USED AS ALTERNATE RETURN POINTS, ! 12657: # THESE PARAMETERS MAY BE REPLACED BY ERROR CODES ! 12658: # ASSEMBLED WITH THE ERR INSTRUCTION. THIS WILL RESULT ! 12659: # IN THE POSTING OF THE ERROR IF THE RETURN IS TAKEN. ! 12660: # ! 12661: # THE PROCEDURES ALL HAVE NAMES CONSISTING OF FIVE LETTERS ! 12662: # AND ARE IN ALPHABETICAL ORDER BY THEIR NAMES. ! 12663: #page ! 12664: # ! 12665: # ACESS - ACCESS VARIABLE VALUE WITH TRACE/INPUT CHECKS ! 12666: # ! 12667: # ACESS LOADS THE VALUE OF A VARIABLE. TRACE AND INPUT ! 12668: # ASSOCIATIONS ARE TESTED FOR AND EXECUTED AS REQUIRED. ! 12669: # ACESS ALSO HANDLES THE SPECIAL CASES OF PSEUDO-VARIABLES. ! 12670: # ! 12671: # (XL) VARIABLE NAME BASE ! 12672: # (WA) VARIABLE NAME OFFSET ! 12673: # JSR ACESS CALL TO ACCESS VALUE ! 12674: # PPM LOC TRANSFER LOC IF ACCESS FAILURE ! 12675: # (XR) VARIABLE VALUE ! 12676: # (WA,WB,WC) DESTROYED ! 12677: # (XL,RA) DESTROYED ! 12678: # ! 12679: # FAILURE CAN OCCUR IF AN INPUT ASSOCIATION CAUSES AN END ! 12680: # OF FILE CONDITION OR IF THE EVALUATION OF AN EXPRESSION ! 12681: # ASSOCIATED WITH AN EXPRESSION VARIABLE FAILS. ! 12682: # ! 12683: acess: #prc # entry point (recursive) ! 12684: movl r10,r9 # copy name base ! 12685: addl2 r6,r9 # point to variable location ! 12686: movl (r9),r9 # load variable value ! 12687: # ! 12688: # LOOP HERE TO CHECK FOR SUCCESSIVE TRBLKS ! 12689: # ! 12690: acs02: cmpl (r9),$b$trt # jump if not trapped ! 12691: beqlu 0f ! 12692: jmp acs18 ! 12693: 0: ! 12694: # ! 12695: # HERE IF TRAPPED ! 12696: # ! 12697: cmpl r9,$trbkv # jump if keyword variable ! 12698: bnequ 0f ! 12699: jmp acs12 ! 12700: 0: ! 12701: cmpl r9,$trbev # jump if not expression variable ! 12702: bnequ acs05 ! 12703: # ! 12704: # HERE FOR EXPRESSION VARIABLE, EVALUATE VARIABLE ! 12705: # ! 12706: movl 4*evexp(r10),r9 # load expression pointer ! 12707: clrl r7 # evaluate by value ! 12708: jsb evalx # evaluate expression ! 12709: .long acs04 # jump if evaluation failure ! 12710: jmp acs02 # check value for more trblks ! 12711: #page ! 12712: # ! 12713: # ACESS (CONTINUED) ! 12714: # ! 12715: # HERE ON READING END OF FILE ! 12716: # ! 12717: acs03: addl2 $4*num03,sp # pop trblk ptr, name base and offset ! 12718: movl r9,dnamp # pop unused scblk ! 12719: # ! 12720: # MERGE HERE WHEN EVALUATION OF EXPRESSION FAILS ! 12721: # ! 12722: acs04: movl (sp)+,r11 # take alternate (failure) return ! 12723: jmp *(r11)+ ! 12724: # ! 12725: # HERE IF NOT KEYWORD OR EXPRESSION VARIABLE ! 12726: # ! 12727: acs05: movl 4*trtyp(r9),r7 # load trap type code ! 12728: tstl r7 # jump if not input association ! 12729: beqlu 0f ! 12730: jmp acs10 ! 12731: 0: ! 12732: tstl kvinp # ignore input assoc if input is off ! 12733: bnequ 0f ! 12734: jmp acs09 ! 12735: 0: ! 12736: # ! 12737: # HERE FOR INPUT ASSOCIATION ! 12738: # ! 12739: movl r10,-(sp) # stack name base ! 12740: movl r6,-(sp) # stack name offset ! 12741: movl r9,-(sp) # stack trblk pointer ! 12742: movl 4*trfpt(r9),r10 # get file ctrl blk ptr or zero ! 12743: tstl r10 # jump if not standard input file ! 12744: bnequ acs06 ! 12745: cmpl 4*trter(r9),$v$ter # jump if terminal ! 12746: bnequ 0f ! 12747: jmp acs21 ! 12748: 0: ! 12749: # ! 12750: # HERE TO READ FROM STANDARD INPUT FILE ! 12751: # ! 12752: movl cswin,r6 # length for read buffer ! 12753: jsb alocs # build string of appropriate length ! 12754: jsb sysrd # read next standard input image ! 12755: .long acs03 # jump to fail exit if end of file ! 12756: jmp acs07 # else merge with other file case ! 12757: # ! 12758: # HERE FOR INPUT FROM OTHER THAN STANDARD INPUT FILE ! 12759: # ! 12760: acs06: movl r10,r6 # fcblk ptr ! 12761: jsb sysil # get input record max length (to wa) ! 12762: jsb alocs # allocate string of correct size ! 12763: movl r10,r6 # fcblk ptr ! 12764: jsb sysin # call system input routine ! 12765: .long acs03 # jump to fail exit if end of file ! 12766: .long acs22 # error ! 12767: .long acs23 # error ! 12768: #page ! 12769: # ! 12770: # ACESS (CONTINUED) ! 12771: # ! 12772: # MERGE HERE AFTER OBTAINING INPUT RECORD ! 12773: # ! 12774: acs07: movl kvtrm,r7 # load trim indicator ! 12775: jsb trimr # trim record as required ! 12776: movl r9,r7 # copy result pointer ! 12777: movl (sp),r9 # reload pointer to trblk ! 12778: # ! 12779: # LOOP TO CHASE TO END OF TRBLK CHAIN AND STORE VALUE ! 12780: # ! 12781: acs08: movl r9,r10 # save pointer to this trblk ! 12782: movl 4*trnxt(r9),r9 # load forward pointer ! 12783: cmpl (r9),$b$trt # loop if this is another trblk ! 12784: beqlu acs08 ! 12785: movl r7,4*trnxt(r10) # else store result at end of chain ! 12786: movl (sp)+,r9 # restore initial trblk pointer ! 12787: movl (sp)+,r6 # restore name offset ! 12788: movl (sp)+,r10 # restore name base pointer ! 12789: # ! 12790: # COME HERE TO MOVE TO NEXT TRBLK ! 12791: # ! 12792: acs09: movl 4*trnxt(r9),r9 # load forward ptr to next value ! 12793: jmp acs02 # back to check if trapped ! 12794: # ! 12795: # HERE TO CHECK FOR ACCESS TRACE TRBLK ! 12796: # ! 12797: acs10: cmpl r7,$trtac # loop back if not access trace ! 12798: beqlu 0f ! 12799: jmp acs09 ! 12800: 0: ! 12801: tstl kvtra # ignore access trace if trace off ! 12802: bnequ 0f ! 12803: jmp acs09 ! 12804: 0: ! 12805: decl kvtra # else decrement trace count ! 12806: tstl 4*trfnc(r9) # jump if print trace ! 12807: beqlu acs11 ! 12808: #page ! 12809: # ! 12810: # ACESS (CONTINUED) ! 12811: # ! 12812: # HERE FOR FULL FUNCTION TRACE ! 12813: # ! 12814: jsb trxeq # call routine to execute trace ! 12815: jmp acs09 # jump for next trblk ! 12816: # ! 12817: # HERE FOR CASE OF PRINT TRACE ! 12818: # ! 12819: acs11: jsb prtsn # print statement number ! 12820: jsb prtnv # print name = value ! 12821: jmp acs09 # jump back for next trblk ! 12822: # ! 12823: # HERE FOR KEYWORD VARIABLE ! 12824: # ! 12825: acs12: movl 4*kvnum(r10),r9 # load keyword number ! 12826: cmpl r9,$k$v$$ # jump if not one word value ! 12827: bgequ acs14 ! 12828: movl l^kvabe(r9),r5 # else load value as integer ! 12829: # ! 12830: # COMMON EXIT WITH KEYWORD VALUE AS INTEGER IN (IA) ! 12831: # ! 12832: acs13: jsb icbld # build icblk ! 12833: jmp acs18 # jump to exit ! 12834: # ! 12835: # HERE IF NOT ONE WORD KEYWORD VALUE ! 12836: # ! 12837: acs14: cmpl r9,$k$s$$ # jump if special case ! 12838: bgequ acs15 ! 12839: subl2 $k$v$$,r9 # else get offset ! 12840: addl2 $ndabo,r9 # point to pattern value ! 12841: jmp acs18 # jump to exit ! 12842: # ! 12843: # HERE IF SPECIAL KEYWORD CASE ! 12844: # ! 12845: acs15: movl kvrtn,r10 # load rtntype in case ! 12846: movl kvstl,r5 # load stlimit in case ! 12847: subl2 $k$s$$,r9 # get case number ! 12848: casel r9,$0,$5 # switch on keyword number ! 12849: 5: ! 12850: .word acs16-5b # jump if alphabet ! 12851: .word acs17-5b # rtntype ! 12852: .word acs19-5b # stcount ! 12853: .word acs20-5b # errtext ! 12854: .word acs13-5b # stlimit ! 12855: #esw # end switch on keyword number ! 12856: #page ! 12857: # ! 12858: # ACESS (CONTINUED) ! 12859: # ! 12860: # ALPHABET ! 12861: # ! 12862: acs16: movl kvalp,r10 # load pointer to alphabet string ! 12863: # ! 12864: # RTNTYPE MERGES HERE ! 12865: # ! 12866: acs17: movl r10,r9 # copy string ptr to proper reg ! 12867: # ! 12868: # COMMON RETURN POINT ! 12869: # ! 12870: acs18: addl2 $4*1,(sp) # return to acess caller ! 12871: rsb ! 12872: # ! 12873: # HERE FOR STCOUNT (IA HAS STLIMIT) ! 12874: # ! 12875: acs19: subl2 kvstc,r5 # stcount = limit - left ! 12876: jmp acs13 # merge back with integer result ! 12877: # ! 12878: # ERRTEXT ! 12879: # ! 12880: acs20: movl r$etx,r9 # get errtext string ! 12881: jmp acs18 # merge with result ! 12882: # ! 12883: # HERE TO READ A RECORD FROM TERMINAL ! 12884: # ! 12885: acs21: movl $rilen,r6 # buffer length ! 12886: jsb alocs # allocate buffer ! 12887: jsb sysri # read record ! 12888: .long acs03 # endfile ! 12889: jmp acs07 # merge with record read ! 12890: # ! 12891: # ERROR RETURNS ! 12892: # ! 12893: acs22: movl r9,dnamp # pop unused scblk ! 12894: jmp er_202 # input from file caused non-recoverable error ! 12895: # ! 12896: acs23: movl r9,dnamp # pop unused scblk ! 12897: jmp er_203 # input file record has incorrect format ! 12898: #enp # end procedure acess ! 12899: #page ! 12900: # ! 12901: # ACOMP -- COMPARE TWO ARITHMETIC VALUES ! 12902: # ! 12903: # 1(XS) FIRST ARGUMENT ! 12904: # 0(XS) SECOND ARGUMENT ! 12905: # JSR ACOMP CALL TO COMPARE VALUES ! 12906: # PPM LOC TRANSFER LOC IF ARG1 IS NON-NUMERIC ! 12907: # PPM LOC TRANSFER LOC IF ARG2 IS NON-NUMERIC ! 12908: # PPM LOC TRANSFER LOC FOR ARG1 LT ARG2 ! 12909: # PPM LOC TRANSFER LOC FOR ARG1 EQ ARG2 ! 12910: # PPM LOC TRANSFER LOC FOR ARG1 GT ARG2 ! 12911: # (NORMAL RETURN IS NEVER GIVEN) ! 12912: # (WA,WB,WC,IA,RA) DESTROYED ! 12913: # (XL,XR) DESTROYED ! 12914: # ! 12915: .data 1 ! 12916: acomp_s: .long 0 ! 12917: .text 0 ! 12918: acomp: movl (sp)+,acomp_s # entry point ! 12919: jsb arith # load arithmetic operands ! 12920: .long acmp7 # jump if first arg non-numeric ! 12921: .long acmp8 # jump if second arg non-numeric ! 12922: .long acmp4 # jump if real arguments ! 12923: # ! 12924: # HERE FOR INTEGER ARGUMENTS ! 12925: # ! 12926: subl2 4*icval(r10),r5 # subtract to compare ! 12927: bvs acmp3 ! 12928: tstl r5 # else jump if arg1 lt arg2 ! 12929: blss acmp5 ! 12930: tstl r5 # jump if arg1 eq arg2 ! 12931: beql acmp2 ! 12932: # ! 12933: # HERE IF ARG1 GT ARG2 ! 12934: # ! 12935: acmp1: addl3 $4*4,acomp_s,r11 # take gt exit ! 12936: jmp *(r11)+ ! 12937: # ! 12938: # HERE IF ARG1 EQ ARG2 ! 12939: # ! 12940: acmp2: addl3 $4*3,acomp_s,r11 # take eq exit ! 12941: jmp *(r11)+ ! 12942: #page ! 12943: # ! 12944: # ACOMP (CONTINUED) ! 12945: # ! 12946: # HERE FOR INTEGER OVERFLOW ON SUBTRACT ! 12947: # ! 12948: acmp3: movl 4*icval(r10),r5 # load second argument ! 12949: tstl r5 # gt if negative ! 12950: blss acmp1 ! 12951: jmp acmp5 # else lt ! 12952: # ! 12953: # HERE FOR REAL OPERANDS ! 12954: # ! 12955: acmp4: subf2 4*rcval(r10),r2 # subtract to compare ! 12956: bvs acmp6 ! 12957: tstf r2 # else jump if arg1 gt ! 12958: bgtr acmp1 ! 12959: tstf r2 # jump if arg1 eq arg2 ! 12960: beql acmp2 ! 12961: # ! 12962: # HERE IF ARG1 LT ARG2 ! 12963: # ! 12964: acmp5: addl3 $4*2,acomp_s,r11 # take lt exit ! 12965: jmp *(r11)+ ! 12966: # ! 12967: # HERE IF OVERFLOW ON REAL SUBTRACTION ! 12968: # ! 12969: acmp6: movf 4*rcval(r10),r2 # reload arg2 ! 12970: tstf r2 # gt if negative ! 12971: blss acmp1 ! 12972: jmp acmp5 # else lt ! 12973: # ! 12974: # HERE IF ARG1 NON-NUMERIC ! 12975: # ! 12976: acmp7: movl acomp_s,r11 # take error exit ! 12977: jmp *(r11)+ ! 12978: # ! 12979: # HERE IF ARG2 NON-NUMERIC ! 12980: # ! 12981: acmp8: addl3 $4*1,acomp_s,r11 # take error exit ! 12982: jmp *(r11)+ ! 12983: #enp # end procedure acomp ! 12984: #page ! 12985: # ! 12986: # ALLOC ALLOCATE BLOCK OF DYNAMIC STORAGE ! 12987: # ! 12988: # (WA) LENGTH REQUIRED IN BYTES ! 12989: # JSR ALLOC CALL TO ALLOCATE BLOCK ! 12990: # (XR) POINTER TO ALLOCATED BLOCK ! 12991: # ! 12992: # A POSSIBLE ALTERNATIVE TO AOV .. AND FOLLOWING STMT IS - ! 12993: # MOV DNAME,XR . SUB WA,XR . BLO XR,DNAMP,ALOC2 . ! 12994: # MOV DNAMP,XR . ADD WA,XR ! 12995: # ! 12996: alloc: #prc # entry point ! 12997: # ! 12998: # COMMON EXIT POINT ! 12999: # ! 13000: aloc1: movl dnamp,r9 # point to next available loc ! 13001: addl2 r6,r9 # point past allocated block ! 13002: bvc 0f ! 13003: jmp aloc2 ! 13004: 0: ! 13005: cmpl r9,dname # jump if not enough room ! 13006: bgtru aloc2 ! 13007: movl r9,dnamp # store new pointer ! 13008: subl2 r6,r9 # point back to start of allocated bk ! 13009: rsb # return to caller ! 13010: # ! 13011: # HERE IF INSUFFICIENT ROOM, TRY A GARBAGE COLLECTION ! 13012: # ! 13013: aloc2: movl r7,allsv # save wb ! 13014: clrl r7 # set no upward move for gbcol ! 13015: jsb gbcol # garbage collect ! 13016: # ! 13017: # SEE IF ROOM AFTER GBCOL OR SYSMM CALL ! 13018: # ! 13019: aloc3: movl dnamp,r9 # point to first available loc ! 13020: addl2 r6,r9 # point past new block ! 13021: bvc 0f ! 13022: jmp alc3a ! 13023: 0: ! 13024: cmpl r9,dname # jump if there is room now ! 13025: blequ aloc4 ! 13026: # ! 13027: # FAILED AGAIN, SEE IF WE CAN GET MORE CORE ! 13028: # ! 13029: alc3a: jsb sysmm # try to get more memory ! 13030: moval 0[r9],r9 # convert to baus (sgd05) ! 13031: addl2 r9,dname # bump ptr by amount obtained ! 13032: tstl r9 # jump if got more core ! 13033: bnequ aloc3 ! 13034: addl2 rsmem,dname # get the reserve memory ! 13035: clrl rsmem # only permissible once ! 13036: incl errft # fatal error ! 13037: jmp er_204 # memory overflow ! 13038: #page ! 13039: # ! 13040: # HERE AFTER SUCCESSFUL GARBAGE COLLECTION ! 13041: # ! 13042: aloc4: movl r5,allia # save ia ! 13043: movl dname,r7 # get dynamic end adrs ! 13044: subl2 dnamp,r7 # compute free store ! 13045: ashl $-2,r7,r7 # convert bytes to words ! 13046: movl r7,r5 # put free store in ia ! 13047: mull2 alfsf,r5 # multiply by free store factor ! 13048: bvs aloc5 ! 13049: movl dname,r7 # dynamic end adrs ! 13050: subl2 dnamb,r7 # compute total amount of dynamic ! 13051: ashl $-2,r7,r7 # convert to words ! 13052: movl r7,aldyn # store it ! 13053: subl2 aldyn,r5 # subtract from scaled up free store ! 13054: tstl r5 # jump if sufficient free store ! 13055: bgtr aloc5 ! 13056: jsb sysmm # try to get more store ! 13057: moval 0[r9],r9 # convert to baus (sgd05) ! 13058: addl2 r9,dname # adjust dynamic end adrs ! 13059: # ! 13060: # MERGE TO RESTORE IA AND WB ! 13061: # ! 13062: aloc5: movl allia,r5 # recover ia ! 13063: movl allsv,r7 # restore wb ! 13064: jmp aloc1 # jump back to exit ! 13065: #enp # end procedure alloc ! 13066: #page ! 13067: # ! 13068: # ALOBF -- ALLOCATE BUFFER ! 13069: # ! 13070: # THIS ROUTINES ALLOCATES A NEW BUFFER. AS THE BFBLK ! 13071: # AND BCBLK COME IN PAIRS, BOTH ARE ALLOCATED HERE, ! 13072: # AND XR POINTS TO THE BCBLK ON RETURN. THE BFBLK ! 13073: # AND BCBLK ARE SET TO THE NULL BUFFER, AND THE IDVAL ! 13074: # IS ZERO ON RETURN. ! 13075: # ! 13076: # (WA) BUFFER SIZE IN CHARACTERS ! 13077: # JSR ALOBF CALL TO CREATE BUFFER ! 13078: # (XR) BCBLK PTR ! 13079: # (WA,WB) DESTROYED ! 13080: # ! 13081: alobf: #prc # entry point ! 13082: movl r6,r7 # hang onto allocation size ! 13083: movab 3+(4*bfsi$)(r6),r6 # get total block size ! 13084: bicl2 $3,r6 ! 13085: cmpl r6,mxlen # check for maxlen exceeded ! 13086: bgequ alb01 ! 13087: addl2 $4*bcsi$,r6 # add in allocation for bcblk ! 13088: jsb alloc # allocate frame ! 13089: movl $b$bct,(r9) # set type ! 13090: clrl 4*idval(r9) # no id yet ! 13091: clrl 4*bclen(r9) # no defined length ! 13092: movl r10,r6 # save xl ! 13093: movl r9,r10 # copy bcblk ptr ! 13094: addl2 $4*bcsi$,r10 # bias past partially built bcblk ! 13095: movl $b$bft,(r10) # set bfblk type word ! 13096: movl r7,4*bfalc(r10) # set allocated size ! 13097: movl r10,4*bcbuf(r9) # set pointer in bcblk ! 13098: clrl 4*bfchr(r10) # clear first word (null pad) ! 13099: movl r6,r10 # restore entry xl ! 13100: rsb # return to caller ! 13101: # ! 13102: # HERE FOR MXLEN EXCEEDED ! 13103: # ! 13104: alb01: jmp er_274 # requested buffer allocation exceeds mxlen ! 13105: #enp # end procedure alobf ! 13106: #page ! 13107: # ! 13108: # ALOCS -- ALLOCATE STRING BLOCK ! 13109: # ! 13110: # ALOCS IS USED TO BUILD A FRAME FOR A STRING BLOCK INTO ! 13111: # WHICH THE ACTUAL CHARACTERS ARE PLACED BY THE CALLER. ! 13112: # ALL STRINGS ARE CREATED WITH A CALL TO ALOCS (THE ! 13113: # EXCEPTIONS OCCUR IN TRIMR AND S$RPL PROCEDURES). ! 13114: # ! 13115: # (WA) LENGTH OF STRING TO BE ALLOCATED ! 13116: # JSR ALOCS CALL TO ALLOCATE SCBLK ! 13117: # (XR) POINTER TO RESULTING SCBLK ! 13118: # (WA) DESTROYED ! 13119: # (WC) CHARACTER COUNT (ENTRY VALUE OF WA) ! 13120: # ! 13121: # THE RESULTING SCBLK HAS THE TYPE WORD AND THE LENGTH ! 13122: # FILLED IN AND THE LAST WORD IS CLEARED TO ZERO CHARACTERS ! 13123: # TO ENSURE CORRECT RIGHT PADDING OF THE FINAL WORD. ! 13124: # ! 13125: alocs: #prc # entry point ! 13126: cmpl r6,kvmxl # jump if length exceeeds maxlength ! 13127: bgtru alcs2 ! 13128: movl r6,r8 # else copy length ! 13129: movab 3+(4*scsi$)(r6),r6 # compute length of scblk in bytes ! 13130: bicl2 $3,r6 ! 13131: movl dnamp,r9 # point to next available location ! 13132: addl2 r6,r9 # point past block ! 13133: bvc 0f ! 13134: jmp alcs0 ! 13135: 0: ! 13136: cmpl r9,dname # jump if there is room ! 13137: blequ alcs1 ! 13138: # ! 13139: # INSUFFICIENT MEMORY ! 13140: # ! 13141: alcs0: clrl r9 # else clear garbage xr value ! 13142: jsb alloc # and use standard allocator ! 13143: addl2 r6,r9 # point past end of block to merge ! 13144: # ! 13145: # MERGE HERE WITH XR POINTING BEYOND NEW BLOCK ! 13146: # ! 13147: alcs1: movl r9,dnamp # set updated storage pointer ! 13148: clrl -(r9) # store zero chars in last word ! 13149: subl2 $4,r6 # decrement length ! 13150: subl2 r6,r9 # point back to start of block ! 13151: movl $b$scl,(r9) # set type word ! 13152: movl r8,4*sclen(r9) # store length in chars ! 13153: rsb # return to alocs caller ! 13154: # ! 13155: # COME HERE IF STRING IS TOO LONG ! 13156: # ! 13157: alcs2: jmp er_205 # string length exceeds value of maxlngth keyword ! 13158: #enp # end procedure alocs ! 13159: #page ! 13160: # ! 13161: # ALOST -- ALLOCATE SPACE IN STATIC REGION ! 13162: # ! 13163: # (WA) LENGTH REQUIRED IN BYTES ! 13164: # JSR ALOST CALL TO ALLOCATE SPACE ! 13165: # (XR) POINTER TO ALLOCATED BLOCK ! 13166: # (WB) DESTROYED ! 13167: # ! 13168: # NOTE THAT THE CODING ENSURES THAT THE RESULTING VALUE ! 13169: # OF STATE IS ALWAYS LESS THAN DNAMB. THIS FACT IS USED ! 13170: # IN TESTING A VARIABLE NAME FOR BEING IN THE STATIC REGION ! 13171: # ! 13172: alost: #prc # entry point ! 13173: # ! 13174: # MERGE BACK HERE AFTER ALLOCATING NEW CHUNK ! 13175: # ! 13176: alst1: movl state,r9 # point to current end of area ! 13177: addl2 r6,r9 # point beyond proposed block ! 13178: bvc 0f ! 13179: jmp alst2 ! 13180: 0: ! 13181: cmpl r9,dnamb # jump if overlap with dynamic area ! 13182: bgequ alst2 ! 13183: movl r9,state # else store new pointer ! 13184: subl2 r6,r9 # point back to start of block ! 13185: rsb # return to alost caller ! 13186: # ! 13187: # HERE IF NO ROOM, PREPARE TO MOVE DYNAMIC STORAGE UP ! 13188: # ! 13189: alst2: movl r6,alsta # save wa ! 13190: cmpl r6,$4*e$sts # skip if requested chunk is large ! 13191: bgequ alst3 ! 13192: movl $4*e$sts,r6 # else set to get large enough chunk ! 13193: # ! 13194: # HERE WITH AMOUNT TO MOVE UP IN WA ! 13195: # ! 13196: alst3: jsb alloc # allocate block to ensure room ! 13197: movl r9,dnamp # and delete it ! 13198: movl r6,r7 # copy move up amount ! 13199: jsb gbcol # call gbcol to move dynamic area up ! 13200: movl alsta,r6 # restore wa ! 13201: jmp alst1 # loop back to try again ! 13202: #enp # end procedure alost ! 13203: #page ! 13204: # ! 13205: # APNDB -- APPEND STRING TO BUFFER ! 13206: # ! 13207: # THIS ROUTINE IS USED BY BUFFER HANDLING ROUTINES TO ! 13208: # APPEND DATA TO AN EXISTING BFBLK. ! 13209: # ! 13210: # (XR) EXISTING BCBLK TO BE APPENDED ! 13211: # (XL) CONVERTABLE TO STRING ! 13212: # JSR APNDB CALL TO APPEND TO BUFFER ! 13213: # PPM LOC THREAD IF (XL) CANT BE CONVERTED ! 13214: # PPM LOC IF NOT ENOUGH ROOM ! 13215: # (WA,WB) DESTROYED ! 13216: # ! 13217: # IF MORE CHARACTERS ARE SPECIFIED THAN CAN BE INSERTED, ! 13218: # THEN NO ACTION IS TAKEN AND THE SECOND RETURN IS TAKEN. ! 13219: # ! 13220: apndb: #prc # entry point ! 13221: movl 4*bclen(r9),r6 # load offset to insert ! 13222: clrl r7 # replace section is null ! 13223: jsb insbf # call to insert at end ! 13224: .long apn01 # convert error ! 13225: .long apn02 # no room ! 13226: addl2 $4*2,(sp) # return to caller ! 13227: rsb ! 13228: # ! 13229: # HERE TO TAKE CONVERT FAILURE EXIT ! 13230: # ! 13231: apn01: movl (sp)+,r11 # return to caller alternate ! 13232: jmp *(r11)+ ! 13233: # ! 13234: # HERE FOR NO FIT EXIT ! 13235: # ! 13236: apn02: addl3 $4*1,(sp)+,r11 # alternate exit to caller ! 13237: jmp *(r11)+ ! 13238: #enp # end procedure apndb ! 13239: #page ! 13240: # ! 13241: # ARITH -- FETCH ARITHMETIC OPERANDS ! 13242: # ! 13243: # ARITH IS USED BY FUNCTIONS AND OPERATORS WHICH EXPECT ! 13244: # TWO NUMERIC ARGUMENTS (OPERANDS) WHICH MUST BOTH BE ! 13245: # INTEGER OR BOTH BE REAL. ARITH FETCHES TWO ARGUMENTS FROM ! 13246: # THE STACK AND PERFORMS ANY NECESSARY CONVERSIONS. ! 13247: # ! 13248: # 1(XS) FIRST ARGUMENT (LEFT OPERAND) ! 13249: # 0(XS) SECOND ARGUMENT (RIGHT OPERAND) ! 13250: # JSR ARITH CALL TO FETCH NUMERIC ARGUMENTS ! 13251: # PPM LOC TRANSFER LOC FOR OPND 1 NON-NUMERIC ! 13252: # PPM LOC TRANSFER LOC FOR OPND 2 NON-NUMERIC ! 13253: # PPM LOC TRANSFER LOC FOR REAL OPERANDS ! 13254: # ! 13255: # FOR INTEGER ARGS, CONTROL RETURNS PAST THE PARAMETERS ! 13256: # ! 13257: # (IA) LEFT OPERAND VALUE ! 13258: # (XR) PTR TO ICBLK FOR LEFT OPERAND ! 13259: # (XL) PTR TO ICBLK FOR RIGHT OPERAND ! 13260: # (XS) POPPED TWICE ! 13261: # (WA,WB,RA) DESTROYED ! 13262: # ! 13263: # FOR REAL ARGUMENTS, CONTROL RETURNS TO THE LOCATION ! 13264: # SPECIFIED BY THE THIRD PARAMETER. ! 13265: # ! 13266: # (RA) LEFT OPERAND VALUE ! 13267: # (XR) PTR TO RCBLK FOR LEFT OPERAND ! 13268: # (XL) PTR TO RCBLK FOR RIGHT OPERAND ! 13269: # (WA,WB,WC) DESTROYED ! 13270: # (XS) POPPED TWICE ! 13271: #page ! 13272: # ! 13273: # ARITH (CONTINUED) ! 13274: # ! 13275: # ENTRY POINT ! 13276: # ! 13277: .data 1 ! 13278: arith_s: .long 0 ! 13279: .text 0 ! 13280: arith: movl (sp)+,arith_s # entry point ! 13281: movl (sp)+,r10 # load right operand ! 13282: movl (sp)+,r9 # load left operand ! 13283: movl (r10),r6 # get right operand type word ! 13284: cmpl r6,$b$icl # jump if integer ! 13285: beqlu arth1 ! 13286: cmpl r6,$b$rcl # jump if real ! 13287: beqlu arth4 ! 13288: movl r9,-(sp) # else replace left arg on stack ! 13289: movl r10,r9 # copy left arg pointer ! 13290: jsb gtnum # convert to numeric ! 13291: .long arth6 # jump if unconvertible ! 13292: movl r9,r10 # else copy converted result ! 13293: movl (r10),r6 # get right operand type word ! 13294: movl (sp)+,r9 # reload left argument ! 13295: cmpl r6,$b$rcl # jump if right arg is real ! 13296: beqlu arth4 ! 13297: # ! 13298: # HERE IF RIGHT ARG IS AN INTEGER ! 13299: # ! 13300: arth1: cmpl (r9),$b$icl # jump if left arg not integer ! 13301: bnequ arth3 ! 13302: # ! 13303: # EXIT FOR INTEGER CASE ! 13304: # ! 13305: arth2: movl 4*icval(r9),r5 # load left operand value ! 13306: addl3 $4*3,arith_s,r11 # return to arith caller ! 13307: jmp (r11) ! 13308: # ! 13309: # HERE FOR RIGHT OPERAND INTEGER, LEFT OPERAND NOT ! 13310: # ! 13311: arth3: jsb gtnum # convert left arg to numeric ! 13312: .long arth7 # jump if not convertible ! 13313: cmpl r6,$b$icl # jump back if integer-integer ! 13314: beqlu arth2 ! 13315: # ! 13316: # HERE WE MUST CONVERT REAL-INTEGER TO REAL-REAL ! 13317: # ! 13318: movl r9,-(sp) # put left arg back on stack ! 13319: movl 4*icval(r10),r5 # load right argument value ! 13320: cvtlf r5,r2 # convert to real ! 13321: jsb rcbld # get real block for right arg, merge ! 13322: movl r9,r10 # copy right arg ptr ! 13323: movl (sp)+,r9 # load left argument ! 13324: jmp arth5 # merge for real-real case ! 13325: #page ! 13326: # ! 13327: # ARITH (CONTINUED) ! 13328: # ! 13329: # HERE IF RIGHT ARGUMENT IS REAL ! 13330: # ! 13331: arth4: cmpl (r9),$b$rcl # jump if left arg real ! 13332: beqlu arth5 ! 13333: jsb gtrea # else convert to real ! 13334: .long arth7 # error if unconvertible ! 13335: # ! 13336: # HERE FOR REAL-REAL ! 13337: # ! 13338: arth5: movf 4*rcval(r9),r2 # load left operand value ! 13339: addl3 $4*2,arith_s,r11 # take real-real exit ! 13340: jmp *(r11)+ ! 13341: # ! 13342: # HERE FOR ERROR CONVERTING RIGHT ARGUMENT ! 13343: # ! 13344: arth6: addl2 $4,sp # pop unwanted left arg ! 13345: addl3 $4*1,arith_s,r11 # take appropriate error exit ! 13346: jmp *(r11)+ ! 13347: # ! 13348: # HERE FOR ERROR CONVERTING LEFT OPERAND ! 13349: # ! 13350: arth7: movl arith_s,r11 # take appropriate error return ! 13351: jmp *(r11)+ ! 13352: #enp # end procedure arith ! 13353: #page ! 13354: # ! 13355: # ASIGN -- PERFORM ASSIGNMENT ! 13356: # ! 13357: # ASIGN PERFORMS THE ASSIGNMENT OF A VALUE TO A VARIABLE ! 13358: # WITH APPROPRIATE CHECKS FOR OUTPUT ASSOCIATIONS AND ! 13359: # VALUE TRACE ASSOCIATIONS WHICH ARE EXECUTED AS REQUIRED. ! 13360: # ASIGN ALSO HANDLES THE SPECIAL CASES OF ASSIGNMENT TO ! 13361: # PATTERN AND EXPRESSION VARIABLES. ! 13362: # ! 13363: # (WB) VALUE TO BE ASSIGNED ! 13364: # (XL) BASE POINTER FOR VARIABLE ! 13365: # (WA) OFFSET FOR VARIABLE ! 13366: # JSR ASIGN CALL TO ASSIGN VALUE TO VARIABLE ! 13367: # PPM LOC TRANSFER LOC FOR FAILURE ! 13368: # (XR,XL,WA,WB,WC) DESTROYED ! 13369: # (RA) DESTROYED ! 13370: # ! 13371: # FAILURE OCCURS IF THE EVALUATION OF AN EXPRESSION ! 13372: # ASSOCIATED WITH AN EXPRESSION VARIABLE FAILS. ! 13373: # ! 13374: asign: #prc # entry point (recursive) ! 13375: # ! 13376: # MERGE BACK HERE TO ASSIGN RESULT TO EXPRESSION VARIABLE. ! 13377: # ! 13378: asg01: addl2 r6,r10 # point to variable value ! 13379: movl (r10),r9 # load variable value ! 13380: cmpl (r9),$b$trt # jump if trapped ! 13381: beqlu asg02 ! 13382: movl r7,(r10) # else perform assignment ! 13383: clrl r10 # clear garbage value in xl ! 13384: addl2 $4*1,(sp) # and return to asign caller ! 13385: rsb ! 13386: # ! 13387: # HERE IF VALUE IS TRAPPED ! 13388: # ! 13389: asg02: subl2 r6,r10 # restore name base ! 13390: cmpl r9,$trbkv # jump if keyword variable ! 13391: bnequ 0f ! 13392: jmp asg14 ! 13393: 0: ! 13394: cmpl r9,$trbev # jump if not expression variable ! 13395: bnequ asg04 ! 13396: # ! 13397: # HERE FOR ASSIGNMENT TO EXPRESSION VARIABLE ! 13398: # ! 13399: movl 4*evexp(r10),r9 # point to expression ! 13400: movl r7,-(sp) # store value to assign on stack ! 13401: movl $num01,r7 # set for evaluation by name ! 13402: jsb evalx # evaluate expression by name ! 13403: .long asg03 # jump if evaluation fails ! 13404: movl (sp)+,r7 # else reload value to assign ! 13405: jmp asg01 # loop back to perform assignment ! 13406: #page ! 13407: # ! 13408: # ASIGN (CONTINUED) ! 13409: # ! 13410: # HERE FOR FAILURE DURING EXPRESSION EVALUATION ! 13411: # ! 13412: asg03: addl2 $4,sp # remove stacked value entry ! 13413: movl (sp)+,r11 # take failure exit ! 13414: jmp *(r11)+ ! 13415: # ! 13416: # HERE IF NOT KEYWORD OR EXPRESSION VARIABLE ! 13417: # ! 13418: asg04: movl r9,-(sp) # save ptr to first trblk ! 13419: # ! 13420: # LOOP TO CHASE DOWN TRBLK CHAIN AND ASSIGN VALUE AT END ! 13421: # ! 13422: asg05: movl r9,r8 # save ptr to this trblk ! 13423: movl 4*trnxt(r9),r9 # point to next trblk ! 13424: cmpl (r9),$b$trt # loop back if another trblk ! 13425: beqlu asg05 ! 13426: movl r8,r9 # else point back to last trblk ! 13427: movl r7,4*trval(r9) # store value at end of chain ! 13428: movl (sp)+,r9 # restore ptr to first trblk ! 13429: # ! 13430: # LOOP TO PROCESS TRBLK ENTRIES ON CHAIN ! 13431: # ! 13432: asg06: movl 4*trtyp(r9),r7 # load type code of trblk ! 13433: cmpl r7,$trtvl # jump if value trace ! 13434: beqlu asg08 ! 13435: cmpl r7,$trtou # jump if output association ! 13436: beqlu asg10 ! 13437: # ! 13438: # HERE TO MOVE TO NEXT TRBLK ON CHAIN ! 13439: # ! 13440: asg07: movl 4*trnxt(r9),r9 # point to next trblk on chain ! 13441: cmpl (r9),$b$trt # loop back if another trblk ! 13442: beqlu asg06 ! 13443: addl2 $4*1,(sp) # else end of chain, return to caller ! 13444: rsb ! 13445: # ! 13446: # HERE TO PROCESS VALUE TRACE ! 13447: # ! 13448: asg08: tstl kvtra # ignore value trace if trace off ! 13449: beqlu asg07 ! 13450: decl kvtra # else decrement trace count ! 13451: tstl 4*trfnc(r9) # jump if print trace ! 13452: beqlu asg09 ! 13453: jsb trxeq # else execute function trace ! 13454: jmp asg07 # and loop back ! 13455: #page ! 13456: # ! 13457: # ASIGN (CONTINUED) ! 13458: # ! 13459: # HERE FOR PRINT TRACE ! 13460: # ! 13461: asg09: jsb prtsn # print statement number ! 13462: jsb prtnv # print name = value ! 13463: jmp asg07 # loop back for next trblk ! 13464: # ! 13465: # HERE FOR OUTPUT ASSOCIATION ! 13466: # ! 13467: asg10: tstl kvoup # ignore output assoc if output off ! 13468: beqlu asg07 ! 13469: movl r9,r10 # else copy trblk pointer ! 13470: movl 4*trval(r8),-(sp)# stack value to output (sgd01) ! 13471: jsb gtstg # convert to string ! 13472: .long asg12 # get datatype name if unconvertible ! 13473: # ! 13474: # MERGE WITH STRING FOR OUTPUT ! 13475: # ! 13476: asg11: movl 4*trfpt(r10),r6 # fcblk ptr ! 13477: tstl r6 # jump if standard output file ! 13478: beqlu asg13 ! 13479: # ! 13480: # HERE FOR OUTPUT TO NON-STANDARD OUTPUT FILE ! 13481: # ! 13482: jsb sysou # call system output routine ! 13483: .long er_206 # output caused file overflow ! 13484: .long er_207 # output caused non-recoverable error ! 13485: addl2 $4*1,(sp) # else all done, return to caller ! 13486: rsb ! 13487: # ! 13488: # IF NOT PRINTABLE, GET DATATYPE NAME INSTEAD ! 13489: # ! 13490: asg12: jsb dtype # call datatype routine ! 13491: jmp asg11 # merge ! 13492: # ! 13493: # HERE TO PRINT A STRING ON THE PRINTER ! 13494: # ! 13495: asg13: jsb prtst # print string value ! 13496: cmpl 4*trter(r10),$v$ter # jump if terminal output ! 13497: bnequ 0f ! 13498: jmp asg20 ! 13499: 0: ! 13500: jsb prtnl # end of line ! 13501: addl2 $4*1,(sp) # return to caller ! 13502: rsb ! 13503: #page ! 13504: # ! 13505: # ASIGN (CONTINUED) ! 13506: # ! 13507: # HERE FOR KEYWORD ASSIGNMENT ! 13508: # ! 13509: asg14: movl 4*kvnum(r10),r10# load keyword number ! 13510: cmpl r10,$k$etx # jump if errtext ! 13511: bnequ 0f ! 13512: jmp asg19 ! 13513: 0: ! 13514: movl r7,r9 # copy value to be assigned ! 13515: jsb gtint # convert to integer ! 13516: .long er_208 # keyword value assigned is not integer ! 13517: movl 4*icval(r9),r5 # else load value ! 13518: cmpl r10,$k$stl # jump if special case of stlimit ! 13519: beqlu asg16 ! 13520: movl r5,r6 # else get addr integer, test ovflow ! 13521: bgeq 0f ! 13522: jmp asg18 ! 13523: 0: ! 13524: cmpl r6,mxlen # fail if too large ! 13525: bgequ asg18 ! 13526: cmpl r10,$k$ert # jump if special case of errtype ! 13527: beqlu asg17 ! 13528: cmpl r10,$k$pfl # jump if special case of profile ! 13529: beqlu asg21 ! 13530: cmpl r10,$k$p$$ # jump unless protected ! 13531: blssu asg15 ! 13532: jmp er_209 # keyword in assignment is protected ! 13533: # ! 13534: # HERE TO DO ASSIGNMENT IF NOT PROTECTED ! 13535: # ! 13536: asg15: movl r6,l^kvabe(r10) # store new value ! 13537: addl2 $4*1,(sp) # return to asign caller ! 13538: rsb ! 13539: # ! 13540: # HERE FOR SPECIAL CASE OF STLIMIT ! 13541: # ! 13542: # SINCE STCOUNT IS MAINTAINED AS (STLIMIT-STCOUNT) ! 13543: # IT IS ALSO NECESSARY TO MODIFY STCOUNT APPROPRIATELY. ! 13544: # ! 13545: asg16: subl2 kvstl,r5 # subtract old limit ! 13546: addl2 kvstc,r5 # add old counter ! 13547: movl r5,kvstc # store new counter value ! 13548: movl 4*icval(r9),r5 # reload new limit value ! 13549: movl r5,kvstl # store new limit value ! 13550: addl2 $4*1,(sp) # return to asign caller ! 13551: rsb ! 13552: # ! 13553: # HERE FOR SPECIAL CASE OF ERRTYPE ! 13554: # ! 13555: asg17: cmpl r6,$nini9 # ok to signal if in range ! 13556: bgtru 0f ! 13557: jmp error ! 13558: 0: ! 13559: # ! 13560: # HERE IF VALUE ASSIGNED IS OUT OF RANGE ! 13561: # ! 13562: asg18: jmp er_210 # keyword value assigned is negative or too large ! 13563: # ! 13564: # HERE FOR SPECIAL CASE OF ERRTEXT ! 13565: # ! 13566: asg19: movl r7,-(sp) # stack value ! 13567: jsb gtstg # convert to string ! 13568: .long er_211 # value assigned to keyword errtext not a string ! 13569: movl r9,r$etx # make assignment ! 13570: addl2 $4*1,(sp) # return to caller ! 13571: rsb ! 13572: # ! 13573: # PRINT STRING TO TERMINAL ! 13574: # ! 13575: asg20: jsb prttr # print ! 13576: addl2 $4*1,(sp) # return ! 13577: rsb ! 13578: # ! 13579: # HERE FOR KEYWORD PROFILE ! 13580: # ! 13581: asg21: cmpl r6,$num02 # moan if not 0,1, or 2 ! 13582: bgtru asg18 ! 13583: tstl r6 # just assign if zero ! 13584: beqlu asg15 ! 13585: tstl pfdmp # branch if first assignment ! 13586: beqlu asg22 ! 13587: cmpl r6,pfdmp # also if same value as before ! 13588: beqlu asg23 ! 13589: jmp er_268 # inconsistent value assigned to keyword profile ! 13590: # ! 13591: asg22: movl r6,pfdmp # note value on first assignment ! 13592: asg23: jsb systm # get the time ! 13593: movl r5,pfstm # fudge some kind of start time ! 13594: jmp asg15 # and go assign ! 13595: #enp # end procedure asign ! 13596: #page ! 13597: # ! 13598: # ASINP -- ASSIGN DURING PATTERN MATCH ! 13599: # ! 13600: # ASINP IS LIKE ASIGN AND HAS A SIMILAR CALLING SEQUENCE ! 13601: # AND EFFECT. THE DIFFERENCE IS THAT THE GLOBAL PATTERN ! 13602: # VARIABLES ARE SAVED AND RESTORED IF REQUIRED. ! 13603: # ! 13604: # (XL) BASE POINTER FOR VARIABLE ! 13605: # (WA) OFFSET FOR VARIABLE ! 13606: # (WB) VALUE TO BE ASSIGNED ! 13607: # JSR ASINP CALL TO ASSIGN VALUE TO VARIABLE ! 13608: # PPM LOC TRANSFER LOC IF FAILURE ! 13609: # (XR,XL) DESTROYED ! 13610: # (WA,WB,WC,RA) DESTROYED ! 13611: # ! 13612: asinp: #prc # entry point, recursive ! 13613: addl2 r6,r10 # point to variable ! 13614: movl (r10),r9 # load current contents ! 13615: cmpl (r9),$b$trt # jump if trapped ! 13616: beqlu asnp1 ! 13617: movl r7,(r10) # else perform assignment ! 13618: clrl r10 # clear garbage value in xl ! 13619: addl2 $4*1,(sp) # return to asinp caller ! 13620: rsb ! 13621: # ! 13622: # HERE IF VARIABLE IS TRAPPED ! 13623: # ! 13624: asnp1: subl2 r6,r10 # restore base pointer ! 13625: movl pmssl,-(sp) # stack subject string length ! 13626: movl pmhbs,-(sp) # stack history stack base ptr ! 13627: movl r$pms,-(sp) # stack subject string pointer ! 13628: movl pmdfl,-(sp) # stack dot flag ! 13629: jsb asign # call full-blown assignment routine ! 13630: .long asnp2 # jump if failure ! 13631: movl (sp)+,pmdfl # restore dot flag ! 13632: movl (sp)+,r$pms # restore subject string pointer ! 13633: movl (sp)+,pmhbs # restore history stack base pointer ! 13634: movl (sp)+,pmssl # restore subject string length ! 13635: addl2 $4*1,(sp) # return to asinp caller ! 13636: rsb ! 13637: # ! 13638: # HERE IF FAILURE IN ASIGN CALL ! 13639: # ! 13640: asnp2: movl (sp)+,pmdfl # restore dot flag ! 13641: movl (sp)+,r$pms # restore subject string pointer ! 13642: movl (sp)+,pmhbs # restore history stack base pointer ! 13643: movl (sp)+,pmssl # restore subject string length ! 13644: movl (sp)+,r11 # take failure exit ! 13645: jmp *(r11)+ ! 13646: #enp # end procedure asinp ! 13647: #page ! 13648: # ! 13649: # BLKLN -- DETERMINE LENGTH OF BLOCK ! 13650: # ! 13651: # BLKLN DETERMINES THE LENGTH OF A BLOCK IN DYNAMIC STORE. ! 13652: # ! 13653: # (WA) FIRST WORD OF BLOCK ! 13654: # (XR) POINTER TO BLOCK ! 13655: # JSR BLKLN CALL TO GET BLOCK LENGTH ! 13656: # (WA) LENGTH OF BLOCK IN BYTES ! 13657: # (XL) DESTROYED ! 13658: # ! 13659: # BLKLN IS USED BY THE GARBAGE COLLECTOR AND IS NOT ! 13660: # PERMITTED TO CALL GBCOL DIRECTLY OR INDIRECTLY. ! 13661: # ! 13662: # THE FIRST WORD STORED IN THE BLOCK (I.E. AT XR) MAY ! 13663: # BE ANYTHING, BUT THE CONTENTS OF WA MUST BE CORRECT. ! 13664: # ! 13665: blkln: #prc # entry point ! 13666: movl r6,r10 # copy first word ! 13667: movzwl -2(r10),r10 # get entry id (bl$xx) ! 13668: casel r10,$0,$bl$$$ # switch on block type ! 13669: 5: ! 13670: .word bln01-5b # arblk ! 13671: .word bln04-5b # bcblk ! 13672: .word bln01-5b # cdblk ! 13673: .word bln01-5b # exblk ! 13674: .word bln07-5b # icblk ! 13675: .word bln03-5b # nmblk ! 13676: .word bln02-5b # p0blk ! 13677: .word bln03-5b # p1blk ! 13678: .word bln04-5b # p2blk ! 13679: .word bln09-5b # rcblk ! 13680: .word bln10-5b # scblk ! 13681: .word bln02-5b # seblk ! 13682: .word bln01-5b # tbblk ! 13683: .word bln01-5b # vcblk ! 13684: .word bln00-5b ! 13685: .word bln00-5b ! 13686: .word bln08-5b # pdblk ! 13687: .word bln05-5b # trblk ! 13688: .word bln11-5b # bfblk ! 13689: .word bln00-5b ! 13690: .word bln00-5b ! 13691: .word bln06-5b # ctblk ! 13692: .word bln01-5b # dfblk ! 13693: .word bln01-5b # efblk ! 13694: .word bln03-5b # evblk ! 13695: .word bln05-5b # ffblk ! 13696: .word bln03-5b # kvblk ! 13697: .word bln01-5b # pfblk ! 13698: .word bln04-5b # teblk ! 13699: #esw # end of jump table on block type ! 13700: #page ! 13701: # ! 13702: # BLKLN (CONTINUED) ! 13703: # ! 13704: # HERE FOR BLOCKS WITH LENGTH IN SECOND WORD ! 13705: # ! 13706: bln00: movl 4*1(r9),r6 # load length ! 13707: rsb # return to blkln caller ! 13708: # ! 13709: # HERE FOR LENGTH IN THIRD WORD (AR,CD,DF,EF,EX,PF,TB,VC) ! 13710: # ! 13711: bln01: movl 4*2(r9),r6 # load length from third word ! 13712: rsb # return to blkln caller ! 13713: # ! 13714: # HERE FOR TWO WORD BLOCKS (P0,SE) ! 13715: # ! 13716: bln02: movl $4*num02,r6 # load length (two words) ! 13717: rsb # return to blkln caller ! 13718: # ! 13719: # HERE FOR THREE WORD BLOCKS (NM,P1,EV,KV) ! 13720: # ! 13721: bln03: movl $4*num03,r6 # load length (three words) ! 13722: rsb # return to blkln caller ! 13723: # ! 13724: # HERE FOR FOUR WORD BLOCKS (P2,TE,BC) ! 13725: # ! 13726: bln04: movl $4*num04,r6 # load length (four words) ! 13727: rsb # return to blkln caller ! 13728: # ! 13729: # HERE FOR FIVE WORD BLOCKS (FF,TR) ! 13730: # ! 13731: bln05: movl $4*num05,r6 # load length ! 13732: rsb # return to blkln caller ! 13733: #page ! 13734: # ! 13735: # BLKLN (CONTINUED) ! 13736: # ! 13737: # HERE FOR CTBLK ! 13738: # ! 13739: bln06: movl $4*ctsi$,r6 # set size of ctblk ! 13740: rsb # return to blkln caller ! 13741: # ! 13742: # HERE FOR ICBLK ! 13743: # ! 13744: bln07: movl $4*icsi$,r6 # set size of icblk ! 13745: rsb # return to blkln caller ! 13746: # ! 13747: # HERE FOR PDBLK ! 13748: # ! 13749: bln08: movl 4*pddfp(r9),r10 # point to dfblk ! 13750: movl 4*dfpdl(r10),r6 # load pdblk length from dfblk ! 13751: rsb # return to blkln caller ! 13752: # ! 13753: # HERE FOR RCBLK ! 13754: # ! 13755: bln09: movl $4*rcsi$,r6 # set size of rcblk ! 13756: rsb # return to blkln caller ! 13757: # ! 13758: # HERE FOR SCBLK ! 13759: # ! 13760: bln10: movl 4*sclen(r9),r6 # load length in characters ! 13761: movab 3+(4*scsi$)(r6),r6 # calculate length in bytes ! 13762: bicl2 $3,r6 ! 13763: rsb # return to blkln caller ! 13764: # ! 13765: # HERE FOR BFBLK ! 13766: # ! 13767: bln11: movl 4*bfalc(r9),r6 # get allocation in bytes ! 13768: movab 3+(4*bfsi$)(r6),r6 # calculate length in bytes ! 13769: bicl2 $3,r6 ! 13770: rsb # return to blkln caller ! 13771: #enp # end procedure blkln ! 13772: #page ! 13773: # ! 13774: # COPYB -- COPY A BLOCK ! 13775: # ! 13776: # (XS) BLOCK TO BE COPIED ! 13777: # JSR COPYB CALL TO COPY BLOCK ! 13778: # PPM LOC RETURN IF BLOCK HAS NO IDVAL FIELD ! 13779: # NORMAL RETURN IF IDVAL FIELD ! 13780: # (XR) COPY OF BLOCK ! 13781: # (XS) POPPED ! 13782: # (XL,WA,WB,WC) DESTROYED ! 13783: # ! 13784: .data 1 ! 13785: copyb_s: .long 0 ! 13786: .text 0 ! 13787: copyb: movl (sp)+,copyb_s # entry point ! 13788: movl (sp),r9 # load argument ! 13789: cmpl r9,$nulls # return argument if it is null ! 13790: bnequ 0f ! 13791: jmp cop10 ! 13792: 0: ! 13793: movl (r9),r6 # else load type word ! 13794: movl r6,r7 # copy type word ! 13795: jsb blkln # get length of argument block ! 13796: movl r9,r10 # copy pointer ! 13797: jsb alloc # allocate block of same size ! 13798: movl r9,(sp) # store pointer to copy ! 13799: jsb sbmvw # copy contents of old block to new ! 13800: movl (sp),r9 # reload pointer to start of copy ! 13801: cmpl r7,$b$tbt # jump if table ! 13802: beqlu cop05 ! 13803: cmpl r7,$b$vct # jump if vector ! 13804: beqlu cop01 ! 13805: cmpl r7,$b$pdt # jump if program defined ! 13806: beqlu cop01 ! 13807: cmpl r7,$b$bct # jump if buffer ! 13808: bnequ 0f ! 13809: jmp cop11 ! 13810: 0: ! 13811: cmpl r7,$b$art # return copy if not array ! 13812: beqlu 0f ! 13813: jmp cop10 ! 13814: 0: ! 13815: # ! 13816: # HERE FOR ARRAY (ARBLK) ! 13817: # ! 13818: addl2 4*arofs(r9),r9 # point to prototype field ! 13819: jmp cop02 # jump to merge ! 13820: # ! 13821: # HERE FOR VECTOR, PROGRAM DEFINED ! 13822: # ! 13823: cop01: addl2 $4*pdfld,r9 # point to pdfld = vcvls ! 13824: # ! 13825: # MERGE HERE FOR ARBLK, VCBLK, PDBLK TO DELETE TRAP ! 13826: # BLOCKS FROM ALL VALUE FIELDS (THE COPY IS UNTRAPPED) ! 13827: # ! 13828: cop02: movl (r9),r10 # load next pointer ! 13829: # ! 13830: # LOOP TO GET VALUE AT END OF TRBLK CHAIN ! 13831: # ! 13832: cop03: cmpl (r10),$b$trt # jump if not trapped ! 13833: bnequ cop04 ! 13834: movl 4*trval(r10),r10# else point to next value ! 13835: jmp cop03 # and loop back ! 13836: #page ! 13837: # ! 13838: # COPYB (CONTINUED) ! 13839: # ! 13840: # HERE WITH UNTRAPPED VALUE IN XL ! 13841: # ! 13842: cop04: movl r10,(r9)+ # store real value, bump pointer ! 13843: cmpl r9,dnamp # loop back if more to go ! 13844: bnequ cop02 ! 13845: jmp cop09 # else jump to exit ! 13846: # ! 13847: # HERE TO COPY A TABLE ! 13848: # ! 13849: cop05: clrl 4*idval(r9) # zero id to stop dump blowing up ! 13850: movl $4*tesi$,r6 # set size of teblk ! 13851: movl $4*tbbuk,r8 # set initial offset ! 13852: # ! 13853: # LOOP THROUGH BUCKETS IN TABLE ! 13854: # ! 13855: cop06: movl (sp),r9 # load table pointer ! 13856: cmpl r8,4*tblen(r9) # jump to exit if all done ! 13857: beqlu cop09 ! 13858: addl2 r8,r9 # else point to next bucket header ! 13859: addl2 $4,r8 # bump offset ! 13860: subl2 $4*tenxt,r9 # subtract link offset to merge ! 13861: # ! 13862: # LOOP THROUGH TEBLKS ON ONE CHAIN ! 13863: # ! 13864: cop07: movl 4*tenxt(r9),r10 # load pointer to next teblk ! 13865: movl (sp),4*tenxt(r9)# set end of chain pointer in case ! 13866: cmpl (r10),$b$tbt # back for next bucket if chain end ! 13867: beqlu cop06 ! 13868: movl r9,-(sp) # else stack ptr to previous block ! 13869: movl $4*tesi$,r6 # set size of teblk ! 13870: jsb alloc # allocate new teblk ! 13871: movl r9,r7 # save ptr to new teblk ! 13872: jsb sbmvw # copy old teblk to new teblk ! 13873: movl r7,r9 # restore pointer to new teblk ! 13874: movl (sp)+,r10 # restore pointer to previous block ! 13875: movl r9,4*tenxt(r10) # link new block to previous ! 13876: movl r9,r10 # copy pointer to new block ! 13877: # ! 13878: # LOOP TO SET REAL VALUE AFTER REMOVING TRAP CHAIN ! 13879: # ! 13880: cop08: movl 4*teval(r10),r10# load value ! 13881: cmpl (r10),$b$trt # loop back if trapped ! 13882: beqlu cop08 ! 13883: movl r10,4*teval(r9) # store untrapped value in teblk ! 13884: jmp cop07 # back for next teblk ! 13885: # ! 13886: # COMMON EXIT POINT ! 13887: # ! 13888: cop09: movl (sp)+,r9 # load pointer to block ! 13889: addl3 $4*1,copyb_s,r11 # return ! 13890: jmp (r11) ! 13891: # ! 13892: # ALTERNATIVE RETURN ! 13893: # ! 13894: cop10: movl copyb_s,r11 # return ! 13895: jmp *(r11)+ ! 13896: #page ! 13897: # ! 13898: # HERE TO COPY BUFFER ! 13899: # ! 13900: cop11: movl 4*bcbuf(r9),r10 # get bfblk ptr ! 13901: movl 4*bfalc(r10),r6 # get allocation ! 13902: movab 3+(4*bfsi$)(r6),r6 # set total size ! 13903: bicl2 $3,r6 ! 13904: movl r9,r10 # save bcblk ptr ! 13905: jsb alloc # allocate bfblk ! 13906: movl 4*bcbuf(r10),r7 # get old bfblk ! 13907: movl r9,4*bcbuf(r10) # set pointer to new bfblk ! 13908: movl r7,r10 # point to old bfblk ! 13909: jsb sbmvw # copy bfblk too ! 13910: clrl r10 # clear rubbish ptr ! 13911: jmp cop09 # branch to exit ! 13912: #enp # end procedure copyb ! 13913: # ! 13914: # CDGCG -- GENERATE CODE FOR COMPLEX GOTO ! 13915: # ! 13916: # USED BY CMPIL TO PROCESS COMPLEX GOTO TREE ! 13917: # ! 13918: # (WB) MUST BE COLLECTABLE ! 13919: # (XR) EXPRESSION POINTER ! 13920: # JSR CDGCG CALL TO GENERATE COMPLEX GOTO ! 13921: # (XL,XR,WA) DESTROYED ! 13922: # ! 13923: cdgcg: #prc # entry point ! 13924: movl 4*cmopn(r9),r10 # get unary goto operator ! 13925: movl 4*cmrop(r9),r9 # point to goto operand ! 13926: cmpl r10,$opdvd # jump if direct goto ! 13927: beqlu cdgc2 ! 13928: jsb cdgnm # generate opnd by name if not direct ! 13929: # ! 13930: # RETURN POINT ! 13931: # ! 13932: cdgc1: movl r10,r6 # goto operator ! 13933: jsb cdwrd # generate it ! 13934: rsb # return to caller ! 13935: # ! 13936: # DIRECT GOTO ! 13937: # ! 13938: cdgc2: jsb cdgvl # generate operand by value ! 13939: jmp cdgc1 # merge to return ! 13940: #enp # end procedure cdgcg ! 13941: #page ! 13942: # ! 13943: # CDGEX -- BUILD EXPRESSION BLOCK ! 13944: # ! 13945: # CDGEX IS PASSED A POINTER TO AN EXPRESSION TREE (SEE ! 13946: # EXPAN) AND RETURNS AN EXPRESSION (SEBLK OR EXBLK). ! 13947: # ! 13948: # (WC) SOME COLLECTABLE VALUE ! 13949: # (WB) INTEGER IN RANGE 0 LE X LE MXLEN ! 13950: # (XL) PTR TO EXPRESSION TREE ! 13951: # JSR CDGEX CALL TO BUILD EXPRESSION ! 13952: # (XR) PTR TO SEBLK OR EXBLK ! 13953: # (XL,WA,WB) DESTROYED ! 13954: # ! 13955: cdgex: #prc # entry point, recursive ! 13956: cmpl (r10),$b$vr$ # jump if not variable ! 13957: blequ cdgx1 ! 13958: # ! 13959: # HERE FOR NATURAL VARIABLE, BUILD SEBLK ! 13960: # ! 13961: movl $4*sesi$,r6 # set size of seblk ! 13962: jsb alloc # allocate space for seblk ! 13963: movl $b$sel,(r9) # set type word ! 13964: movl r10,4*sevar(r9) # store vrblk pointer ! 13965: rsb # return to cdgex caller ! 13966: # ! 13967: # HERE IF NOT VARIABLE, BUILD EXBLK ! 13968: # ! 13969: cdgx1: movl r10,r9 # copy tree pointer ! 13970: movl r8,-(sp) # save wc ! 13971: movl cwcof,r10 # save current offset ! 13972: movl (r9),r6 # get type word ! 13973: cmpl r6,$b$cmt # call by value if not cmblk ! 13974: bnequ cdgx2 ! 13975: cmpl 4*cmtyp(r9),$c$$nm # jump if cmblk only by value ! 13976: bgequ cdgx2 ! 13977: #page ! 13978: # ! 13979: # CDGEX (CONTINUED) ! 13980: # ! 13981: # HERE IF EXPRESSION CAN BE EVALUATED BY NAME ! 13982: # ! 13983: jsb cdgnm # generate code by name ! 13984: movl $ornm$,r6 # load return by name word ! 13985: jmp cdgx3 # merge with value case ! 13986: # ! 13987: # HERE IF EXPRESSION CAN ONLY BE EVALUATED BY VALUE ! 13988: # ! 13989: cdgx2: jsb cdgvl # generate code by value ! 13990: movl $orvl$,r6 # load return by value word ! 13991: # ! 13992: # MERGE HERE TO CONSTRUCT EXBLK ! 13993: # ! 13994: cdgx3: jsb cdwrd # generate return word ! 13995: jsb exbld # build exblk ! 13996: movl (sp)+,r8 # restore wc ! 13997: rsb # return to cdgex caller ! 13998: #enp # end procedure cdgex ! 13999: #page ! 14000: # ! 14001: # CDGNM -- GENERATE CODE BY NAME ! 14002: # ! 14003: # CDGNM IS CALLED DURING THE COMPILATION PROCESS TO ! 14004: # GENERATE CODE BY NAME FOR AN EXPRESSION. SEE CDBLK ! 14005: # DESCRIPTION FOR DETAILS OF CODE GENERATED. THE INPUT ! 14006: # TO CDGNM IS AN EXPRESSION TREE AS GENERATED BY EXPAN. ! 14007: # ! 14008: # CDGNM IS A RECURSIVE PROCEDURE WHICH PROCEEDS BY MAKING ! 14009: # RECURSIVE CALLS TO GENERATE CODE FOR OPERANDS. ! 14010: # ! 14011: # (WB) INTEGER IN RANGE 0 LE N LE DNAMB ! 14012: # (XR) PTR TO TREE GENERATED BY EXPAN ! 14013: # (WC) CONSTANT FLAG (SEE BELOW) ! 14014: # JSR CDGNM CALL TO GENERATE CODE BY NAME ! 14015: # (XR,WA) DESTROYED ! 14016: # (WC) SET NON-ZERO IF NON-CONSTANT ! 14017: # ! 14018: # WC IS SET TO A NON-ZERO (COLLECTABLE) VALUE IF THE ! 14019: # EXPRESSION FOR WHICH CODE IS GENERATED CANNOT BE ! 14020: # EVALUATED AT COMPILE TIME, OTHERWISE WC IS UNCHANGED. ! 14021: # ! 14022: # THE CODE IS GENERATED IN THE CURRENT CCBLK (SEE CDWRD). ! 14023: # ! 14024: cdgnm: #prc # entry point, recursive ! 14025: movl r10,-(sp) # save entry xl ! 14026: movl r7,-(sp) # save entry wb ! 14027: jsb sbchk # check for stack overflow ! 14028: movl (r9),r6 # load type word ! 14029: cmpl r6,$b$cmt # jump if cmblk ! 14030: beqlu cgn04 ! 14031: cmpl r6,$b$vr$ # jump if simple variable ! 14032: blssu 0f ! 14033: jmp cgn02 ! 14034: 0: ! 14035: # ! 14036: # MERGE HERE FOR OPERAND YIELDING VALUE (E.G. CONSTANT) ! 14037: # ! 14038: cgn01: jmp er_212 # syntax error. value used where name is required ! 14039: # ! 14040: # HERE FOR NATURAL VARIABLE REFERENCE ! 14041: # ! 14042: cgn02: movl $olvn$,r6 # load variable load call ! 14043: jsb cdwrd # generate it ! 14044: movl r9,r6 # copy vrblk pointer ! 14045: jsb cdwrd # generate vrblk pointer ! 14046: #page ! 14047: # ! 14048: # CDGNM (CONTINUED) ! 14049: # ! 14050: # HERE TO EXIT WITH WC SET CORRECTLY ! 14051: # ! 14052: cgn03: movl (sp)+,r7 # restore entry wb ! 14053: movl (sp)+,r10 # restore entry xl ! 14054: rsb # return to cdgnm caller ! 14055: # ! 14056: # HERE FOR CMBLK ! 14057: # ! 14058: cgn04: movl r9,r10 # copy cmblk pointer ! 14059: movl 4*cmtyp(r9),r9 # load cmblk type ! 14060: cmpl r9,$c$$nm # error if not name operand ! 14061: bgequ cgn01 ! 14062: casel r9,$0,$c$$nm # else switch on type ! 14063: 5: ! 14064: .word cgn05-5b # array reference ! 14065: .word cgn08-5b # function call ! 14066: .word cgn09-5b # deferred expression ! 14067: .word cgn10-5b # indirect reference ! 14068: .word cgn11-5b # keyword reference ! 14069: .word cgn08-5b # undefined binary op ! 14070: .word cgn08-5b # undefined unary op ! 14071: #esw # end switch on cmblk type ! 14072: # ! 14073: # HERE TO GENERATE CODE FOR ARRAY REFERENCE ! 14074: # ! 14075: cgn05: movl $4*cmopn,r7 # point to array operand ! 14076: # ! 14077: # LOOP TO GENERATE CODE FOR ARRAY OPERAND AND SUBSCRIPTS ! 14078: # ! 14079: cgn06: jsb cmgen # generate code for next operand ! 14080: movl 4*cmlen(r10),r8 # load length of cmblk ! 14081: cmpl r7,r8 # loop till all generated ! 14082: blssu cgn06 ! 14083: # ! 14084: # GENERATE APPROPRIATE ARRAY CALL ! 14085: # ! 14086: movl $oaon$,r6 # load one-subscript case call ! 14087: cmpl r8,$4*cmar1 # jump to exit if one subscript case ! 14088: beqlu cgn07 ! 14089: movl $oamn$,r6 # else load multi-subscript case call ! 14090: jsb cdwrd # generate call ! 14091: movl r8,r6 # copy cmblk length ! 14092: ashl $-2,r6,r6 # convert to words ! 14093: subl2 $cmvls,r6 # calculate number of subscripts ! 14094: #page ! 14095: # ! 14096: # CDGNM (CONTINUED) ! 14097: # ! 14098: # HERE TO EXIT GENERATING WORD (NON-CONSTANT) ! 14099: # ! 14100: cgn07: movl sp,r8 # set result non-constant ! 14101: jsb cdwrd # generate word ! 14102: jmp cgn03 # back to exit ! 14103: # ! 14104: # HERE TO GENERATE CODE FOR FUNCTIONS AND UNDEFINED OPRS ! 14105: # ! 14106: cgn08: movl r10,r9 # copy cmblk pointer ! 14107: jsb cdgvl # gen code by value for call ! 14108: movl $ofne$,r6 # get extra call for by name ! 14109: jmp cgn07 # back to generate and exit ! 14110: # ! 14111: # HERE TO GENERATE CODE FOR DEFERED EXPRESSION ! 14112: # ! 14113: cgn09: movl 4*cmrop(r10),r9 # check if variable ! 14114: cmpl (r9),$b$vr$ # treat *variable as simple var ! 14115: blssu 0f ! 14116: jmp cgn02 ! 14117: 0: ! 14118: movl r9,r10 # copy ptr to expression tree ! 14119: jsb cdgex # else build exblk ! 14120: movl $olex$,r6 # set call to load expr by name ! 14121: jsb cdwrd # generate it ! 14122: movl r9,r6 # copy exblk pointer ! 14123: jsb cdwrd # generate exblk pointer ! 14124: jmp cgn03 # back to exit ! 14125: # ! 14126: # HERE TO GENERATE CODE FOR INDIRECT REFERENCE ! 14127: # ! 14128: cgn10: movl 4*cmrop(r10),r9 # get operand ! 14129: jsb cdgvl # generate code by value for it ! 14130: movl $oinn$,r6 # load call for indirect by name ! 14131: jmp cgn12 # merge ! 14132: # ! 14133: # HERE TO GENERATE CODE FOR KEYWORD REFERENCE ! 14134: # ! 14135: cgn11: movl 4*cmrop(r10),r9 # get operand ! 14136: jsb cdgnm # generate code by name for it ! 14137: movl $okwn$,r6 # load call for keyword by name ! 14138: # ! 14139: # KEYWORD, INDIRECT MERGE HERE ! 14140: # ! 14141: cgn12: jsb cdwrd # generate code for operator ! 14142: jmp cgn03 # exit ! 14143: #enp # end procedure cdgnm ! 14144: #page ! 14145: # ! 14146: # CDGVL -- GENERATE CODE BY VALUE ! 14147: # ! 14148: # CDGVL IS CALLED DURING THE COMPILATION PROCESS TO ! 14149: # GENERATE CODE BY VALUE FOR AN EXPRESSION. SEE CDBLK ! 14150: # DESCRIPTION FOR DETAILS OF THE CODE GENERATED. THE INPUT ! 14151: # TO CDGVL IS AN EXPRESSION TREE AS GENERATED BY EXPAN. ! 14152: # ! 14153: # CDGVL IS A RECURSIVE PROCEDURE WHICH PROCEEDS BY MAKING ! 14154: # RECURSIVE CALLS TO GENERATE CODE FOR OPERANDS. ! 14155: # ! 14156: # (WB) INTEGER IN RANGE 0 LE N LE DNAMB ! 14157: # (XR) PTR TO TREE GENERATED BY EXPAN ! 14158: # (WC) CONSTANT FLAG (SEE BELOW) ! 14159: # JSR CDGVL CALL TO GENERATE CODE BY VALUE ! 14160: # (XR,WA) DESTROYED ! 14161: # (WC) SET NON-ZERO IF NON-CONSTANT ! 14162: # ! 14163: # WC IS SET TO A NON-ZERO (COLLECTABLE) VALUE IF THE ! 14164: # EXPRESSION FOR WHICH CODE IS GENERATED CANNOT BE ! 14165: # EVALUATED AT COMPILE TIME, OTHERWISE WC IS UNCHANGED. ! 14166: # ! 14167: # IF WC IS NON-ZERO ON ENTRY, THEN PREEVALUATION IS NOT ! 14168: # ALLOWED REGARDLESS OF THE NATURE OF THE OPERAND. ! 14169: # ! 14170: # THE CODE IS GENERATED IN THE CURRENT CCBLK (SEE CDWRD). ! 14171: # ! 14172: cdgvl: #prc # entry point, recursive ! 14173: movl (r9),r6 # load type word ! 14174: cmpl r6,$b$cmt # jump if cmblk ! 14175: beqlu cgv01 ! 14176: cmpl r6,$b$vra # jump if icblk, rcblk, scblk ! 14177: blssu cgv00 ! 14178: tstl 4*vrlen(r9) # jump if not system variable ! 14179: bnequ cgvl0 ! 14180: movl r9,-(sp) # stack xr ! 14181: movl 4*vrsvp(r9),r9 # point to svblk ! 14182: movl 4*svbit(r9),r6 # get svblk property bits ! 14183: movl (sp)+,r9 # recover xr ! 14184: mcoml btckw,r11 # check if constant keyword ! 14185: bicl2 r11,r6 ! 14186: tstl r6 # jump if constant keyword ! 14187: bnequ cgv00 ! 14188: # ! 14189: # HERE FOR VARIABLE VALUE REFERENCE ! 14190: # ! 14191: cgvl0: movl sp,r8 # indicate non-constant value ! 14192: # ! 14193: # MERGE HERE FOR SIMPLE CONSTANT (ICBLK,RCBLK,SCBLK) ! 14194: # AND FOR VARIABLES CORRESPONDING TO CONSTANT KEYWORDS. ! 14195: # ! 14196: cgv00: movl r9,r6 # copy ptr to var or constant ! 14197: jsb cdwrd # generate as code word ! 14198: rsb # return to caller ! 14199: #page ! 14200: # ! 14201: # CDGVL (CONTINUED) ! 14202: # ! 14203: # HERE FOR TREE NODE (CMBLK) ! 14204: # ! 14205: cgv01: movl r7,-(sp) # save entry wb ! 14206: movl r10,-(sp) # save entry xl ! 14207: movl r8,-(sp) # save entry constant flag ! 14208: movl cwcof,-(sp) # save initial code offset ! 14209: jsb sbchk # check for stack overflow ! 14210: # ! 14211: # PREPARE TO GENERATE CODE FOR CMBLK. WC IS SET TO THE ! 14212: # VALUE OF CSWNO (ZERO IF -OPTIMISE, 1 IF -NOOPT) TO ! 14213: # START WITH AND IS RESET NON-ZERO FOR ANY NON-CONSTANT ! 14214: # CODE GENERATED. IF IT IS STILL ZERO AFTER GENERATING ALL ! 14215: # THE CMBLK CODE, THEN ITS VALUE IS COMPUTED AS THE RESULT. ! 14216: # ! 14217: movl r9,r10 # copy cmblk pointer ! 14218: movl 4*cmtyp(r9),r9 # load cmblk type ! 14219: movl cswno,r8 # reset constant flag ! 14220: cmpl r9,$c$pr$ # jump if not predicate value ! 14221: blequ cgv02 ! 14222: movl sp,r8 # else force non-constant case ! 14223: # ! 14224: # HERE WITH WC SET APPROPRIATELY ! 14225: # ! 14226: cgv02: casel r9,$0,$c$$nv # switch to appropriate generator ! 14227: 5: ! 14228: .word cgv03-5b # array reference ! 14229: .word cgv05-5b # function call ! 14230: .word cgv14-5b # deferred expression ! 14231: .word cgv31-5b # indirect reference ! 14232: .word cgv27-5b # keyword reference ! 14233: .word cgv29-5b # undefined binop ! 14234: .word cgv30-5b # undefined unop ! 14235: .word cgv18-5b # binops with val opds ! 14236: .word cgv19-5b # unops with valu opnd ! 14237: .word cgv18-5b # alternation ! 14238: .word cgv24-5b # concatenation ! 14239: .word cgv24-5b # concatenation (not pattern match) ! 14240: .word cgv27-5b # unops with name opnd ! 14241: .word cgv26-5b # binary $ and . ! 14242: .word cgv21-5b # assignment ! 14243: .word cgv31-5b # interrogation ! 14244: .word cgv28-5b # negation ! 14245: .word cgv15-5b # selection ! 14246: .word cgv18-5b # pattern match ! 14247: #esw # end switch on cmblk type ! 14248: #page ! 14249: # ! 14250: # CDGVL (CONTINUED) ! 14251: # ! 14252: # HERE TO GENERATE CODE FOR ARRAY REFERENCE ! 14253: # ! 14254: cgv03: movl $4*cmopn,r7 # set offset to array operand ! 14255: # ! 14256: # LOOP TO GENERATE CODE FOR ARRAY OPERAND AND SUBSCRIPTS ! 14257: # ! 14258: cgv04: jsb cmgen # gen value code for next operand ! 14259: movl 4*cmlen(r10),r8 # load cmblk length ! 14260: cmpl r7,r8 # loop back if more to go ! 14261: blssu cgv04 ! 14262: # ! 14263: # GENERATE CALL TO APPROPRIATE ARRAY REFERENCE ROUTINE ! 14264: # ! 14265: movl $oaov$,r6 # set one subscript call in case ! 14266: cmpl r8,$4*cmar1 # jump to exit if 1-sub case ! 14267: bnequ 0f ! 14268: jmp cgv32 ! 14269: 0: ! 14270: movl $oamv$,r6 # else set call for multi-subscripts ! 14271: jsb cdwrd # generate call ! 14272: movl r8,r6 # copy length of cmblk ! 14273: subl2 $4*cmvls,r6 # subtract standard length ! 14274: ashl $-2,r6,r6 # get number of words ! 14275: jmp cgv32 # jump to generate subscript count ! 14276: # ! 14277: # HERE TO GENERATE CODE FOR FUNCTION CALL ! 14278: # ! 14279: cgv05: movl $4*cmvls,r7 # set offset to first argument ! 14280: # ! 14281: # LOOP TO GENERATE CODE FOR ARGUMENTS ! 14282: # ! 14283: cgv06: cmpl r7,4*cmlen(r10) # jump if all generated ! 14284: beqlu cgv07 ! 14285: jsb cmgen # else gen value code for next arg ! 14286: jmp cgv06 # back to generate next argument ! 14287: # ! 14288: # HERE TO GENERATE ACTUAL FUNCTION CALL ! 14289: # ! 14290: cgv07: subl2 $4*cmvls,r7 # get number of arg ptrs (bytes) ! 14291: ashl $-2,r7,r7 # convert bytes to words ! 14292: movl 4*cmopn(r10),r9 # load function vrblk pointer ! 14293: tstl 4*vrlen(r9) # jump if not system function ! 14294: bnequ cgv12 ! 14295: movl 4*vrsvp(r9),r10 # load svblk ptr if system var ! 14296: movl 4*svbit(r10),r6 # load bit mask ! 14297: mcoml btffc,r11 # test for fast function call allowed ! 14298: bicl2 r11,r6 ! 14299: tstl r6 # jump if not ! 14300: beqlu cgv12 ! 14301: #page ! 14302: # ! 14303: # CDGVL (CONTINUED) ! 14304: # ! 14305: # HERE IF FAST FUNCTION CALL IS ALLOWED ! 14306: # ! 14307: movl 4*svbit(r10),r6 # reload bit indicators ! 14308: mcoml btpre,r11 # test for preevaluation ok ! 14309: bicl2 r11,r6 ! 14310: tstl r6 # jump if preevaluation permitted ! 14311: bnequ cgv08 ! 14312: movl sp,r8 # else set result non-constant ! 14313: # ! 14314: # TEST FOR CORRECT NUMBER OF ARGS FOR FAST CALL ! 14315: # ! 14316: cgv08: movl 4*vrfnc(r9),r10 # load ptr to svfnc field ! 14317: movl 4*fargs(r10),r6 # load svnar field value ! 14318: cmpl r6,r7 # jump if argument count is correct ! 14319: beqlu cgv11 ! 14320: cmpl r6,r7 # jump if too few arguments given ! 14321: bgequ cgv09 ! 14322: # ! 14323: # HERE IF TOO MANY ARGUMENTS, PREPARE TO GENERATE O$POPS ! 14324: # ! 14325: subl2 r6,r7 # get number of extra args ! 14326: # set as count to control loop ! 14327: movl $opop$,r6 # set pop call ! 14328: jmp cgv10 # jump to common loop ! 14329: # ! 14330: # HERE IF TOO FEW ARGUMENTS, PREPARE TO GENERATE NULLS ! 14331: # ! 14332: cgv09: subl2 r7,r6 # get number of missing arguments ! 14333: movl r6,r7 # load as count to control loop ! 14334: movl $nulls,r6 # load ptr to null constant ! 14335: # ! 14336: # LOOP TO GENERATE CALLS TO FIX ARGUMENT COUNT ! 14337: # ! 14338: cgv10: jsb cdwrd # generate one call ! 14339: sobgtr r7,cgv10 # loop till all generated ! 14340: # ! 14341: # HERE AFTER ADJUSTING ARG COUNT AS REQUIRED ! 14342: # ! 14343: cgv11: movl r10,r6 # copy pointer to svfnc field ! 14344: jmp cgv36 # jump to generate call ! 14345: #page ! 14346: # ! 14347: # CDGVL (CONTINUED) ! 14348: # ! 14349: # COME HERE IF FAST CALL IS NOT PERMITTED ! 14350: # ! 14351: cgv12: movl $ofns$,r6 # set one arg call in case ! 14352: cmpl r7,$num01 # jump if one arg case ! 14353: beqlu cgv13 ! 14354: movl $ofnc$,r6 # else load call for more than 1 arg ! 14355: jsb cdwrd # generate it ! 14356: movl r7,r6 # copy argument count ! 14357: # ! 14358: # ONE ARG CASE MERGES HERE ! 14359: # ! 14360: cgv13: jsb cdwrd # generate =o$fns or arg count ! 14361: movl r9,r6 # copy vrblk pointer ! 14362: jmp cgv32 # jump to generate vrblk ptr ! 14363: # ! 14364: # HERE FOR DEFERRED EXPRESSION ! 14365: # ! 14366: cgv14: movl 4*cmrop(r10),r10# point to expression tree ! 14367: jsb cdgex # build exblk or seblk ! 14368: movl r9,r6 # copy block ptr ! 14369: jsb cdwrd # generate ptr to exblk or seblk ! 14370: jmp cgv34 # jump to exit, constant test ! 14371: # ! 14372: # HERE TO GENERATE CODE FOR SELECTION ! 14373: # ! 14374: cgv15: clrl -(sp) # zero ptr to chain of forward jumps ! 14375: clrl -(sp) # zero ptr to prev o$slc forward ptr ! 14376: movl $4*cmvls,r7 # point to first alternative ! 14377: movl $osla$,r6 # set initial code word ! 14378: # ! 14379: # 0(XS) IS THE OFFSET TO THE PREVIOUS WORD ! 14380: # WHICH REQUIRES FILLING IN WITH AN ! 14381: # OFFSET TO THE FOLLOWING O$SLC,O$SLD ! 14382: # ! 14383: # 1(XS) IS THE HEAD OF A CHAIN OF OFFSET ! 14384: # POINTERS INDICATING THOSE LOCATIONS ! 14385: # TO BE FILLED WITH OFFSETS PAST ! 14386: # THE END OF ALL THE ALTERNATIVES ! 14387: # ! 14388: cgv16: jsb cdwrd # generate o$slc (o$sla first time) ! 14389: movl cwcof,(sp) # set current loc as ptr to fill in ! 14390: jsb cdwrd # generate garbage word there for now ! 14391: jsb cmgen # gen value code for alternative ! 14392: movl $oslb$,r6 # load o$slb pointer ! 14393: jsb cdwrd # generate o$slb call ! 14394: movl 4*1(sp),r6 # load old chain ptr ! 14395: movl cwcof,4*1(sp) # set current loc as new chain head ! 14396: jsb cdwrd # generate forward chain link ! 14397: #page ! 14398: # ! 14399: # CDGVL (CONTINUED) ! 14400: # ! 14401: # NOW TO FILL IN THE SKIP OFFSET TO O$SLC,O$SLD ! 14402: # ! 14403: movl (sp),r9 # load offset to word to plug ! 14404: addl2 r$ccb,r9 # point to actual location to plug ! 14405: movl cwcof,(r9) # plug proper offset in ! 14406: movl $oslc$,r6 # load o$slc ptr for next alternative ! 14407: movl r7,r9 # copy offset (destroy garbage xr) ! 14408: addl2 $4,r9 # bump extra time for test ! 14409: cmpl r9,4*cmlen(r10) # loop back if not last alternative ! 14410: blssu cgv16 ! 14411: # ! 14412: # HERE TO GENERATE CODE FOR LAST ALTERNATIVE ! 14413: # ! 14414: movl $osld$,r6 # get header call ! 14415: jsb cdwrd # generate o$sld call ! 14416: jsb cmgen # generate code for last alternative ! 14417: addl2 $4,sp # pop offset ptr ! 14418: movl (sp)+,r9 # load chain ptr ! 14419: # ! 14420: # LOOP TO PLUG OFFSETS PAST STRUCTURE ! 14421: # ! 14422: cgv17: addl2 r$ccb,r9 # make next ptr absolute ! 14423: movl (r9),r6 # load forward ptr ! 14424: movl cwcof,(r9) # plug required offset ! 14425: movl r6,r9 # copy forward ptr ! 14426: tstl r6 # loop back if more to go ! 14427: bnequ cgv17 ! 14428: jmp cgv33 # else jump to exit (not constant) ! 14429: # ! 14430: # HERE FOR BINARY OPS WITH VALUE OPERANDS ! 14431: # ! 14432: cgv18: movl 4*cmlop(r10),r9 # load left operand pointer ! 14433: jsb cdgvl # gen value code for left operand ! 14434: # ! 14435: # HERE FOR UNARY OPS WITH VALUE OPERAND (BINOPS MERGE) ! 14436: # ! 14437: cgv19: movl 4*cmrop(r10),r9 # load right (only) operand ptr ! 14438: jsb cdgvl # gen code by value ! 14439: #page ! 14440: # ! 14441: # CDGVL (CONTINUED) ! 14442: # ! 14443: # MERGE HERE TO GENERATE OPERATOR CALL FROM CMOPN FIELD ! 14444: # ! 14445: cgv20: movl 4*cmopn(r10),r6 # load operator call pointer ! 14446: jmp cgv36 # jump to generate it with cons test ! 14447: # ! 14448: # HERE FOR ASSIGNMENT ! 14449: # ! 14450: cgv21: movl 4*cmlop(r10),r9 # load left operand pointer ! 14451: cmpl (r9),$b$vr$ # jump if not variable ! 14452: blequ cgv22 ! 14453: # ! 14454: # HERE FOR ASSIGNMENT TO SIMPLE VARIABLE ! 14455: # ! 14456: movl 4*cmrop(r10),r9 # load right operand ptr ! 14457: jsb cdgvl # generate code by value ! 14458: movl 4*cmlop(r10),r6 # reload left operand vrblk ptr ! 14459: addl2 $4*vrsto,r6 # point to vrsto field ! 14460: jmp cgv32 # jump to generate store ptr ! 14461: # ! 14462: # HERE IF NOT SIMPLE VARIABLE ASSIGNMENT ! 14463: # ! 14464: cgv22: jsb expap # test for pattern match on left side ! 14465: .long cgv23 # jump if not pattern match ! 14466: # ! 14467: # HERE FOR PATTERN REPLACEMENT ! 14468: # ! 14469: movl 4*cmrop(r9),4*cmlop(r10) # save pattern ptr in safe place ! 14470: movl 4*cmlop(r9),r9 # load subject ptr ! 14471: jsb cdgnm # gen code by name for subject ! 14472: movl 4*cmlop(r10),r9 # load pattern ptr ! 14473: jsb cdgvl # gen code by value for pattern ! 14474: movl $opmn$,r6 # load match by name call ! 14475: jsb cdwrd # generate it ! 14476: movl 4*cmrop(r10),r9 # load replacement value ptr ! 14477: jsb cdgvl # gen code by value ! 14478: movl $orpl$,r6 # load replace call ! 14479: jmp cgv32 # jump to gen and exit (not constant) ! 14480: # ! 14481: # HERE FOR ASSIGNMENT TO COMPLEX VARIABLE ! 14482: # ! 14483: cgv23: movl sp,r8 # inhibit pre-evaluation ! 14484: jsb cdgnm # gen code by name for left side ! 14485: jmp cgv31 # merge with unop circuit ! 14486: #page ! 14487: # ! 14488: # CDGVL (CONTINUED) ! 14489: # ! 14490: # HERE FOR CONCATENATION ! 14491: # ! 14492: cgv24: movl 4*cmlop(r10),r9 # load left operand ptr ! 14493: cmpl (r9),$b$cmt # ordinary binop if not cmblk ! 14494: beqlu 0f ! 14495: jmp cgv18 ! 14496: 0: ! 14497: movl 4*cmtyp(r9),r7 # load cmblk type code ! 14498: cmpl r7,$c$int # special case if interrogation ! 14499: beqlu cgv25 ! 14500: cmpl r7,$c$neg # or negation ! 14501: beqlu cgv25 ! 14502: cmpl r7,$c$fnc # else ordinary binop if not function ! 14503: beqlu 0f ! 14504: jmp cgv18 ! 14505: 0: ! 14506: movl 4*cmopn(r9),r9 # else load function vrblk ptr ! 14507: tstl 4*vrlen(r9) # ordinary binop if not system var ! 14508: beqlu 0f ! 14509: jmp cgv18 ! 14510: 0: ! 14511: movl 4*vrsvp(r9),r9 # else point to svblk ! 14512: movl 4*svbit(r9),r6 # load bit indicators ! 14513: mcoml btprd,r11 # test for predicate function ! 14514: bicl2 r11,r6 ! 14515: tstl r6 # ordinary binop if not ! 14516: bnequ 0f ! 14517: jmp cgv18 ! 14518: 0: ! 14519: # ! 14520: # HERE IF LEFT ARG OF CONCATENATION IS PREDICATE FUNCTION ! 14521: # ! 14522: cgv25: movl 4*cmlop(r10),r9 # reload left arg ! 14523: jsb cdgvl # gen code by value ! 14524: movl $opop$,r6 # load pop call ! 14525: jsb cdwrd # generate it ! 14526: movl 4*cmrop(r10),r9 # load right operand ! 14527: jsb cdgvl # gen code by value as result code ! 14528: jmp cgv33 # exit (not constant) ! 14529: # ! 14530: # HERE TO GENERATE CODE FOR PATTERN, IMMEDIATE ASSIGNMENT ! 14531: # ! 14532: cgv26: movl 4*cmlop(r10),r9 # load left operand ! 14533: jsb cdgvl # gen code by value, merge ! 14534: # ! 14535: # HERE FOR UNOPS WITH ARG BY NAME (BINARY $ . MERGE) ! 14536: # ! 14537: cgv27: movl 4*cmrop(r10),r9 # load right operand ptr ! 14538: jsb cdgnm # gen code by name for right arg ! 14539: movl 4*cmopn(r10),r9 # get operator code word ! 14540: cmpl (r9),$o$kwv # gen call unless keyword value ! 14541: beqlu 0f ! 14542: jmp cgv20 ! 14543: 0: ! 14544: #page ! 14545: # ! 14546: # CDGVL (CONTINUED) ! 14547: # ! 14548: # HERE FOR KEYWORD BY VALUE. THIS IS CONSTANT ONLY IF ! 14549: # THE OPERAND IS ONE OF THE SPECIAL SYSTEM VARIABLES WITH ! 14550: # THE SVCKW BIT SET TO INDICATE A CONSTANT KEYWORD VALUE. ! 14551: # NOTE THAT THE ONLY CONSTANT OPERAND BY NAME IS A VARIABLE ! 14552: # ! 14553: tstl r8 # gen call if non-constant (not var) ! 14554: beqlu 0f ! 14555: jmp cgv20 ! 14556: 0: ! 14557: movl sp,r8 # else set non-constant in case ! 14558: movl 4*cmrop(r10),r9 # load ptr to operand vrblk ! 14559: tstl 4*vrlen(r9) # gen (non-constant) if not sys var ! 14560: beqlu 0f ! 14561: jmp cgv20 ! 14562: 0: ! 14563: movl 4*vrsvp(r9),r9 # else load ptr to svblk ! 14564: movl 4*svbit(r9),r6 # load bit mask ! 14565: mcoml btckw,r11 # test for constant keyword ! 14566: bicl2 r11,r6 ! 14567: tstl r6 # go gen if not constant ! 14568: bnequ 0f ! 14569: jmp cgv20 ! 14570: 0: ! 14571: clrl r8 # else set result constant ! 14572: jmp cgv20 # and jump back to generate call ! 14573: # ! 14574: # HERE TO GENERATE CODE FOR NEGATION ! 14575: # ! 14576: cgv28: movl $onta$,r6 # get initial word ! 14577: jsb cdwrd # generate it ! 14578: movl cwcof,r7 # save next offset ! 14579: jsb cdwrd # generate gunk word for now ! 14580: movl 4*cmrop(r10),r9 # load right operand ptr ! 14581: jsb cdgvl # gen code by value ! 14582: movl $ontb$,r6 # load end of evaluation call ! 14583: jsb cdwrd # generate it ! 14584: movl r7,r9 # copy offset to word to plug ! 14585: addl2 r$ccb,r9 # point to actual word to plug ! 14586: movl cwcof,(r9) # plug word with current offset ! 14587: movl $ontc$,r6 # load final call ! 14588: jmp cgv32 # jump to generate it (not constant) ! 14589: # ! 14590: # HERE TO GENERATE CODE FOR UNDEFINED BINARY OPERATOR ! 14591: # ! 14592: cgv29: movl 4*cmlop(r10),r9 # load left operand ptr ! 14593: jsb cdgvl # generate code by value ! 14594: #page ! 14595: # ! 14596: # CDGVL (CONTINUED) ! 14597: # ! 14598: # HERE TO GENERATE CODE FOR UNDEFINED UNARY OPERATOR ! 14599: # ! 14600: cgv30: movl $c$uo$,r7 # set unop code + 1 ! 14601: subl2 4*cmtyp(r10),r7 # set number of args (1 or 2) ! 14602: # ! 14603: # MERGE HERE FOR UNDEFINED OPERATORS ! 14604: # ! 14605: movl 4*cmrop(r10),r9 # load right (only) operand pointer ! 14606: jsb cdgvl # gen value code for right operand ! 14607: movl 4*cmopn(r10),r9 # load pointer to operator dv ! 14608: movl 4*dvopn(r9),r9 # load pointer offset ! 14609: moval 0[r9],r9 # convert word offset to bytes ! 14610: addl2 $r$uba,r9 # point to proper function ptr ! 14611: subl2 $4*vrfnc,r9 # set standard function offset ! 14612: jmp cgv12 # merge with function call circuit ! 14613: # ! 14614: # HERE TO GENERATE CODE FOR INTERROGATION, INDIRECTION ! 14615: # ! 14616: cgv31: movl sp,r8 # set non constant ! 14617: jmp cgv19 # merge ! 14618: # ! 14619: # HERE TO EXIT GENERATING A WORD, RESULT NOT CONSTANT ! 14620: # ! 14621: cgv32: jsb cdwrd # generate word, merge ! 14622: # ! 14623: # HERE TO EXIT WITH NO WORD GENERATED, NOT CONSTANT ! 14624: # ! 14625: cgv33: movl sp,r8 # indicate result is not constant ! 14626: # ! 14627: # COMMON EXIT POINT ! 14628: # ! 14629: cgv34: addl2 $4,sp # pop initial code offset ! 14630: movl (sp)+,r6 # restore old constant flag ! 14631: movl (sp)+,r10 # restore entry xl ! 14632: movl (sp)+,r7 # restore entry wb ! 14633: tstl r8 # jump if not constant ! 14634: bnequ cgv35 ! 14635: movl r6,r8 # else restore entry constant flag ! 14636: # ! 14637: # HERE TO RETURN AFTER DEALING WITH WC SETTING ! 14638: # ! 14639: cgv35: rsb # return to cdgvl caller ! 14640: # ! 14641: # EXIT HERE TO GENERATE WORD AND TEST FOR CONSTANT ! 14642: # ! 14643: cgv36: jsb cdwrd # generate word ! 14644: tstl r8 # jump to exit if not constant ! 14645: bnequ cgv34 ! 14646: #page ! 14647: # ! 14648: # CDGVL (CONTINUED) ! 14649: # ! 14650: # HERE TO PREEVALUATE CONSTANT SUB-EXPRESSION ! 14651: # ! 14652: movl $orvl$,r6 # load call to return value ! 14653: jsb cdwrd # generate it ! 14654: movl (sp),r10 # load initial code offset ! 14655: jsb exbld # build exblk for expression ! 14656: clrl r7 # set to evaluate by value ! 14657: jsb evalx # evaluate expression ! 14658: .long invalid$ # should not fail ! 14659: movl (r9),r6 # load type word of result ! 14660: cmpl r6,$p$aaa # jump if not pattern ! 14661: blequ cgv37 ! 14662: movl $olpt$,r6 # else load special pattern load call ! 14663: jsb cdwrd # generate it ! 14664: # ! 14665: # MERGE HERE TO GENERATE POINTER TO RESULTING CONSTANT ! 14666: # ! 14667: cgv37: movl r9,r6 # copy constant pointer ! 14668: jsb cdwrd # generate ptr ! 14669: clrl r8 # set result constant ! 14670: jmp cgv34 # jump back to exit ! 14671: #enp # end procedure cdgvl ! 14672: #page ! 14673: # ! 14674: # CDWRD -- GENERATE ONE WORD OF CODE ! 14675: # ! 14676: # CDWRD WRITES ONE WORD INTO THE CURRENT CODE BLOCK UNDER ! 14677: # CONSTRUCTION. A NEW, LARGER, BLOCK IS ALLOCATED IF THERE ! 14678: # IS INSUFFICIENT ROOM IN THE CURRENT BLOCK. CDWRD ENSURES ! 14679: # THAT THERE ARE AT LEAST THREE WORDS LEFT IN THE BLOCK ! 14680: # AFTER ENTERING THE NEW WORD. THIS GUARANTEES THAT ANY ! 14681: # EXTRA SPACE AT THE END CAN BE SPLIT OFF AS A CCBLK. ! 14682: # ! 14683: # (WA) WORD TO BE GENERATED ! 14684: # JSR CDWRD CALL TO GENERATE WORD ! 14685: # ! 14686: cdwrd: #prc # entry point ! 14687: movl r9,-(sp) # save entry xr ! 14688: movl r6,-(sp) # save code word to be generated ! 14689: # ! 14690: # MERGE BACK HERE AFTER ALLOCATING LARGER BLOCK ! 14691: # ! 14692: cdwd1: movl r$ccb,r9 # load ptr to ccblk being built ! 14693: tstl r9 # jump if block allocated ! 14694: bnequ cdwd2 ! 14695: # ! 14696: # HERE WE ALLOCATE AN ENTIRELY FRESH BLOCK ! 14697: # ! 14698: movl $4*e$cbs,r6 # load initial length ! 14699: jsb alloc # allocate ccblk ! 14700: movl $b$cct,(r9) # store type word ! 14701: movl $4*cccod,cwcof # set initial offset ! 14702: movl r6,4*cclen(r9) # store block length ! 14703: movl r9,r$ccb # store ptr to new block ! 14704: # ! 14705: # HERE WE HAVE A BLOCK WE CAN USE ! 14706: # ! 14707: cdwd2: movl cwcof,r6 # load current offset ! 14708: addl2 $4*num04,r6 # adjust for test (four words) ! 14709: cmpl r6,4*cclen(r9) # jump if room in this block ! 14710: bgtru 0f ! 14711: jmp cdwd4 ! 14712: 0: ! 14713: # ! 14714: # HERE IF NO ROOM IN CURRENT BLOCK ! 14715: # ! 14716: cmpl r6,mxlen # jump if already at max size ! 14717: blssu 0f ! 14718: jmp cdwd5 ! 14719: 0: ! 14720: addl2 $4*e$cbs,r6 # else get new size ! 14721: movl r10,-(sp) # save entry xl ! 14722: movl r9,r10 # copy pointer ! 14723: cmpl r6,mxlen # jump if not too large ! 14724: blssu cdwd3 ! 14725: movl mxlen,r6 # else reset to max allowed size ! 14726: #page ! 14727: # ! 14728: # CDWRD (CONTINUED) ! 14729: # ! 14730: # HERE WITH NEW BLOCK SIZE IN WA ! 14731: # ! 14732: cdwd3: jsb alloc # allocate new block ! 14733: movl r9,r$ccb # store pointer to new block ! 14734: movl $b$cct,(r9)+ # store type word in new block ! 14735: movl r6,(r9)+ # store block length ! 14736: addl2 $4*ccuse,r10 # point to ccuse,cccod fields in old ! 14737: movl (r10),r6 # load ccuse value ! 14738: jsb sbmvw # copy useful words from old block ! 14739: movl (sp)+,r10 # restore xl ! 14740: jmp cdwd1 # merge back to try again ! 14741: # ! 14742: # HERE WITH ROOM IN CURRENT BLOCK ! 14743: # ! 14744: cdwd4: movl cwcof,r6 # load current offset ! 14745: addl2 $4,r6 # get new offset ! 14746: movl r6,cwcof # store new offset ! 14747: movl r6,4*ccuse(r9) # store in ccblk for gbcol ! 14748: subl2 $4,r6 # restore ptr to this word ! 14749: addl2 r6,r9 # point to current entry ! 14750: movl (sp)+,r6 # reload word to generate ! 14751: movl r6,(r9) # store word in block ! 14752: movl (sp)+,r9 # restore entry xr ! 14753: rsb # return to caller ! 14754: # ! 14755: # HERE IF COMPILED CODE IS TOO LONG FOR CDBLK ! 14756: # ! 14757: cdwd5: jmp er_213 # syntax error. statement is too complicated. ! 14758: #enp # end procedure cdwrd ! 14759: #page ! 14760: # ! 14761: # CMGEN -- GENERATE CODE FOR CMBLK PTR ! 14762: # ! 14763: # CMGEN IS A SUBSIDIARY PROCEDURE USED TO GENERATE VALUE ! 14764: # CODE FOR A CMBLK PTR FROM THE MAIN CODE GENERATORS. ! 14765: # ! 14766: # (XL) CMBLK POINTER ! 14767: # (WB) OFFSET TO POINTER IN CMBLK ! 14768: # JSR CMGEN CALL TO GENERATE CODE ! 14769: # (XR,WA) DESTROYED ! 14770: # (WB) BUMPED BY ONE WORD ! 14771: # ! 14772: cmgen: #prc # entry point, recursive ! 14773: movl r10,r9 # copy cmblk pointer ! 14774: addl2 r7,r9 # point to cmblk pointer ! 14775: movl (r9),r9 # load cmblk pointer ! 14776: jsb cdgvl # generate code by value ! 14777: addl2 $4,r7 # bump offset ! 14778: rsb # return to caller ! 14779: #enp # end procedure cmgen ! 14780: #page ! 14781: # ! 14782: # CMPIL (COMPILE SOURCE CODE) ! 14783: # ! 14784: # CMPIL IS USED TO CONVERT SNOBOL4 SOURCE CODE TO INTERNAL ! 14785: # FORM (SEE CDBLK FORMAT). IT IS USED BOTH FOR THE INITIAL ! 14786: # COMPILE AND AT RUN TIME BY THE CODE AND CONVERT FUNCTIONS ! 14787: # THIS PROCEDURE HAS CONTROL FOR THE ENTIRE DURATION OF ! 14788: # INITIAL COMPILATION. AN ERROR IN ANY PROCEDURE CALLED ! 14789: # DURING COMPILATION WILL LEAD FIRST TO THE ERROR SECTION ! 14790: # AND ULTIMATELY BACK HERE FOR RESUMED COMPILATION. THE ! 14791: # RE-ENTRY POINTS AFTER AN ERROR ARE SPECIALLY LABELLED - ! 14792: # ! 14793: # CMPCE RESUME AFTER CONTROL CARD ERROR ! 14794: # CMPLE RESUME AFTER LABEL ERROR ! 14795: # CMPSE RESUME AFTER STATEMENT ERROR ! 14796: # ! 14797: # JSR CMPIL CALL TO COMPILE CODE ! 14798: # (XR) PTR TO CDBLK FOR ENTRY STATEMENT ! 14799: # (XL,WA,WB,WC,RA) DESTROYED ! 14800: # ! 14801: # THE FOLLOWING GLOBAL VARIABLES ARE REFERENCED ! 14802: # ! 14803: # CMPSN NUMBER OF NEXT STATEMENT ! 14804: # TO BE COMPILED. ! 14805: # ! 14806: # CSWXX CONTROL CARD SWITCH VALUES ARE ! 14807: # CHANGED WHEN RELEVANT CONTROL ! 14808: # CARDS ARE MET. ! 14809: # ! 14810: # CWCOF OFFSET TO NEXT WORD IN CODE BLOCK ! 14811: # BEING BUILT (SEE CDWRD). ! 14812: # ! 14813: # LSTSN NUMBER OF STATEMENT MOST RECENTLY ! 14814: # COMPILED (INITIALLY SET TO ZERO). ! 14815: # ! 14816: # R$CIM CURRENT (INITIAL) COMPILER IMAGE ! 14817: # (ZERO FOR INITIAL COMPILE CALL) ! 14818: # ! 14819: # R$CNI USED TO POINT TO FOLLOWING IMAGE. ! 14820: # (SEE READR PROCEDURE). ! 14821: # ! 14822: # SCNGO GOTO SWITCH FOR SCANE PROCEDURE ! 14823: # ! 14824: # SCNIL LENGTH OF CURRENT IMAGE EXCLUDING ! 14825: # CHARACTERS REMOVED BY -INPUT. ! 14826: # ! 14827: # SCNPT CURRENT SCAN OFFSET, SEE SCANE. ! 14828: # ! 14829: # SCNRS RESCAN SWITCH FOR SCANE PROCEDURE. ! 14830: # ! 14831: # SCNSE OFFSET (IN R$CIM) OF MOST RECENTLY ! 14832: # SCANNED ELEMENT. SET ZERO IF NOT ! 14833: # CURRENTLY SCANNING ITEMS ! 14834: #page ! 14835: # ! 14836: # CMPIL (CONTINUED) ! 14837: # ! 14838: # STAGE STGIC INITIAL COMPILE IN PROGRESS ! 14839: # STGXC CODE/CONVERT COMPILE ! 14840: # STGEV BUILDING EXBLK FOR EVAL ! 14841: # STGXT EXECUTE TIME (OUTSIDE COMPILE) ! 14842: # STGCE INITIAL COMPILE AFTER END LINE ! 14843: # STGXE EXECUTE COMPILE AFTER END LINE ! 14844: # ! 14845: # CMPIL ALSO USES A FIXED NUMBER OF LOCATIONS ON THE ! 14846: # MAIN STACK AS FOLLOWS. (THE DEFINITIONS OF THE ACTUAL ! 14847: # OFFSETS ARE IN THE DEFINITIONS SECTION). ! 14848: # ! 14849: # CMSTM(XS) POINTER TO EXPAN TREE FOR BODY OF ! 14850: # STATEMENT (SEE EXPAN PROCEDURE). ! 14851: # ! 14852: # CMSGO(XS) POINTER TO TREE REPRESENTATION OF ! 14853: # SUCCESS GOTO (SEE PROCEDURE SCNGO)9 ! 14854: # ZERO IF NO SUCCESS GOTO IS GIVEN ! 14855: # ! 14856: # CMFGO(XS) LIKE CMSGO FOR FAILURE GOTO. ! 14857: # ! 14858: # CMCGO(XS) SET NON-ZERO ONLY IF THERE IS A ! 14859: # CONDITIONAL GOTO. USED FOR -FAIL, ! 14860: # -NOFAIL CODE GENERATION. ! 14861: # ! 14862: # CMPCD(XS) POINTER TO CDBLK FOR PREVIOUS ! 14863: # STATEMENT. ZERO FOR 1ST STATEMENT. ! 14864: # ! 14865: # CMFFP(XS) SET NON-ZERO IF CDFAL IN PREVIOUS ! 14866: # CDBLK NEEDS FILLING WITH FORWARD ! 14867: # POINTER, ELSE SET TO ZERO. ! 14868: # ! 14869: # CMFFC(XS) SAME AS CMFFP FOR CURRENT CDBLK ! 14870: # ! 14871: # CMSOP(XS) OFFSET TO WORD IN PREVIOUS CDBLK ! 14872: # TO BE FILLED IN WITH FORWARD PTR ! 14873: # TO NEXT CDBLK FOR SUCCESS GOTO. ! 14874: # ZERO IF NO FILL IN IS REQUIRED. ! 14875: # ! 14876: # CMSOC(XS) SAME AS CMSOP FOR CURRENT CDBLK. ! 14877: # ! 14878: # CMLBL(XS) POINTER TO VRBLK FOR LABEL OF ! 14879: # CURRENT STATEMENT. ZERO IF NO LABEL ! 14880: # ! 14881: # CMTRA(XS) POINTER TO CDBLK FOR ENTRY STMNT. ! 14882: #page ! 14883: # ! 14884: # CMPIL (CONTINUED) ! 14885: # ! 14886: # ENTRY POINT ! 14887: # ! 14888: cmpil: #prc # entry point ! 14889: movl $cmnen,r7 # set number of stack work locations ! 14890: # ! 14891: # LOOP TO INITIALIZE STACK WORKING LOCATIONS ! 14892: # ! 14893: cmp00: clrl -(sp) # store a zero, make one entry ! 14894: sobgtr r7,cmp00 # loop back until all set ! 14895: movl sp,cmpxs # save stack pointer for error sec ! 14896: #sss cmpss # save s-r stack pointer if any ! 14897: # ! 14898: # LOOP THROUGH STATEMENTS ! 14899: # ! 14900: cmp01: movl scnpt,r7 # set scan pointer offset ! 14901: movl r7,scnse # set start of element location ! 14902: movl $ocer$,r6 # point to compile error call ! 14903: jsb cdwrd # generate as temporary cdfal ! 14904: cmpl r7,scnil # jump if chars left on this image ! 14905: blssu cmp04 ! 14906: # ! 14907: # LOOP HERE AFTER COMMENT OR CONTROL CARD ! 14908: # ALSO SPECIAL ENTRY AFTER CONTROL CARD ERROR ! 14909: # ! 14910: cmpce: clrl r9 # clear possible garbage xr value ! 14911: cmpl stage,$stgic # skip unless initial compile ! 14912: bnequ cmp02 ! 14913: jsb readr # read next input image ! 14914: tstl r9 # jump if no input available ! 14915: bnequ 0f ! 14916: jmp cmp09 ! 14917: 0: ! 14918: jsb nexts # acquire next source image ! 14919: movl cmpsn,lstsn # store stmt no for use by listr ! 14920: clrl scnpt # reset scan pointer ! 14921: jmp cmp04 # go process image ! 14922: # ! 14923: # FOR EXECUTE TIME COMPILE, PERMIT EMBEDDED CONTROL CARDS ! 14924: # AND COMMENTS (BY SKIPPING TO NEXT SEMI-COLON) ! 14925: # ! 14926: cmp02: movl r$cim,r9 # get current image ! 14927: movl scnpt,r7 # get current offset ! 14928: movab cfp$f(r9)[r7],r9# prepare to get chars ! 14929: # ! 14930: # SKIP TO SEMI-COLON ! 14931: # ! 14932: cmp03: movzbl (r9)+,r8 # get char ! 14933: incl scnpt # advance offset ! 14934: cmpl r8,$ch$sm # skip if semi-colon found ! 14935: beqlu cmp04 ! 14936: cmpl scnpt,scnil # loop if more chars ! 14937: blssu cmp03 ! 14938: clrl r9 # clear garbage xr value ! 14939: jmp cmp09 # end of image ! 14940: #page ! 14941: # ! 14942: # CMPIL (CONTINUED) ! 14943: # ! 14944: # HERE WITH IMAGE AVAILABLE TO SCAN. NOTE THAT IF THE INPUT ! 14945: # STRING IS NULL, THEN EVERYTHING IS OK SINCE NULL IS ! 14946: # ACTUALLY ASSEMBLED AS A WORD OF BLANKS. ! 14947: # ! 14948: cmp04: movl r$cim,r9 # point to current image ! 14949: movl scnpt,r7 # load current offset ! 14950: movl r7,r6 # copy for label scan ! 14951: movab cfp$f(r9)[r7],r9# point to first character ! 14952: movzbl (r9)+,r8 # load first character ! 14953: cmpl r8,$ch$sm # no label if semicolon ! 14954: bnequ 0f ! 14955: jmp cmp12 ! 14956: 0: ! 14957: cmpl r8,$ch$as # loop back if comment card ! 14958: bnequ 0f ! 14959: jmp cmpce ! 14960: 0: ! 14961: cmpl r8,$ch$mn # jump if control card ! 14962: bnequ 0f ! 14963: jmp cmp32 ! 14964: 0: ! 14965: movl r$cim,r$cmp # about to destroy r$cim ! 14966: movl $cmlab,r10 # point to label work string ! 14967: movl r10,r$cim # scane is to scan work string ! 14968: movab cfp$f(r10),r10 # point to first character position ! 14969: movb r8,(r10)+ # store char just loaded ! 14970: movl $ch$sm,r8 # get a semicolon ! 14971: movb r8,(r10) # store after first char ! 14972: #csc r10 # finished character storing ! 14973: clrl r10 # clear pointer ! 14974: clrl scnpt # start at first character ! 14975: movl scnil,-(sp) # preserve image length ! 14976: movl $num02,scnil # read 2 chars at most ! 14977: jsb scane # scan first char for type ! 14978: movl (sp)+,scnil # restore image length ! 14979: movl r10,r8 # note return code ! 14980: movl r$cmp,r10 # get old r$cim ! 14981: movl r10,r$cim # put it back ! 14982: movl r7,scnpt # reinstate offset ! 14983: tstl scnbl # blank seen - cant be label ! 14984: beqlu 0f ! 14985: jmp cmp12 ! 14986: 0: ! 14987: movl r10,r9 # point to current image ! 14988: movab cfp$f(r9)[r7],r9# point to first char again ! 14989: cmpl r8,$t$var # ok if letter ! 14990: beqlu cmp06 ! 14991: cmpl r8,$t$con # ok if digit ! 14992: beqlu cmp06 ! 14993: # ! 14994: # DROP IN OR JUMP FROM ERROR SECTION IF SCANE FAILED ! 14995: # ! 14996: cmple: movl r$cmp,r$cim # point to bad line ! 14997: jmp er_214 # bad label or misplaced continuation line ! 14998: # ! 14999: # LOOP TO SCAN LABEL ! 15000: # ! 15001: cmp05: cmpl r8,$ch$sm # skip if semicolon ! 15002: beqlu cmp07 ! 15003: incl r6 # bump offset ! 15004: cmpl r6,scnil # jump if end of image (label end) ! 15005: beqlu cmp07 ! 15006: #page ! 15007: # ! 15008: # CMPIL (CONTINUED) ! 15009: # ! 15010: # ENTER LOOP AT THIS POINT ! 15011: # ! 15012: cmp06: movzbl (r9)+,r8 # else load next character ! 15013: cmpl r8,$ch$ht # jump if horizontal tab ! 15014: beqlu cmp07 ! 15015: cmpl r8,$ch$bl # loop back if non-blank ! 15016: bnequ cmp05 ! 15017: # ! 15018: # HERE AFTER SCANNING OUT LABEL ! 15019: # ! 15020: cmp07: movl r6,scnpt # save updated scan offset ! 15021: subl2 r7,r6 # get length of label ! 15022: tstl r6 # skip if label length zero ! 15023: bnequ 0f ! 15024: jmp cmp12 ! 15025: 0: ! 15026: clrl r9 # clear garbage xr value ! 15027: jsb sbstr # build scblk for label name ! 15028: jsb gtnvr # locate/contruct vrblk ! 15029: .long invalid$ # dummy (impossible) error return ! 15030: movl r9,4*cmlbl(sp) # store label pointer ! 15031: tstl 4*vrlen(r9) # jump if not system label ! 15032: bnequ cmp11 ! 15033: cmpl 4*vrsvp(r9),$v$end # jump if not end label ! 15034: bnequ cmp11 ! 15035: # ! 15036: # HERE FOR END LABEL SCANNED OUT ! 15037: # ! 15038: addl2 $stgnd,stage # adjust stage appropriately ! 15039: jsb scane # scan out next element ! 15040: cmpl r10,$t$smc # jump if end of image ! 15041: bnequ 0f ! 15042: jmp cmp10 ! 15043: 0: ! 15044: cmpl r10,$t$var # else error if not variable ! 15045: bnequ cmp08 ! 15046: # ! 15047: # HERE CHECK FOR VALID INITIAL TRANSFER ! 15048: # ! 15049: cmpl 4*vrlbl(r9),$stndl # jump if not defined (error) ! 15050: beqlu cmp08 ! 15051: movl 4*vrlbl(r9),4*cmtra(sp) # else set initial entry pointer ! 15052: jsb scane # scan next element ! 15053: cmpl r10,$t$smc # jump if ok (end of image) ! 15054: bnequ 0f ! 15055: jmp cmp10 ! 15056: 0: ! 15057: # ! 15058: # HERE FOR BAD TRANSFER LABEL ! 15059: # ! 15060: cmp08: jmp er_215 # syntax error. undefined or erroneous entry label ! 15061: # ! 15062: # HERE FOR END OF INPUT (NO END LABEL DETECTED) ! 15063: # ! 15064: cmp09: addl2 $stgnd,stage # adjust stage appropriately ! 15065: cmpl stage,$stgxe # jump if code call (ok) ! 15066: bnequ 0f ! 15067: jmp cmp10 ! 15068: 0: ! 15069: jmp er_216 # syntax error. missing end line ! 15070: # ! 15071: # HERE AFTER PROCESSING END LINE (MERGE HERE ON END ERROR) ! 15072: # ! 15073: cmp10: movl $ostp$,r6 # set stop call pointer ! 15074: jsb cdwrd # generate as statement call ! 15075: jmp cmpse # jump to generate as failure ! 15076: #page ! 15077: # ! 15078: # CMPIL (CONTINUED) ! 15079: # ! 15080: # HERE AFTER PROCESSING LABEL OTHER THAN END ! 15081: # ! 15082: cmp11: cmpl stage,$stgic # jump if code call - redef. ok ! 15083: beqlu 0f ! 15084: jmp cmp12 ! 15085: 0: ! 15086: cmpl 4*vrlbl(r9),$stndl # else check for redefinition ! 15087: bnequ 0f ! 15088: jmp cmp12 ! 15089: 0: ! 15090: clrl 4*cmlbl(sp) # leave first label decln undisturbed ! 15091: jmp er_217 # syntax error. duplicate label ! 15092: # ! 15093: # HERE AFTER DEALING WITH LABEL ! 15094: # ! 15095: cmp12: clrl r7 # set flag for statement body ! 15096: jsb expan # get tree for statement body ! 15097: movl r9,4*cmstm(sp) # store for later use ! 15098: clrl 4*cmsgo(sp) # clear success goto pointer ! 15099: clrl 4*cmfgo(sp) # clear failure goto pointer ! 15100: clrl 4*cmcgo(sp) # clear conditional goto flag ! 15101: jsb scane # scan next element ! 15102: cmpl r10,$t$col # jump it not colon (no goto) ! 15103: beqlu 0f ! 15104: jmp cmp18 ! 15105: 0: ! 15106: # ! 15107: # LOOP TO PROCESS GOTO FIELDS ! 15108: # ! 15109: cmp13: movl sp,scngo # set goto flag ! 15110: jsb scane # scan next element ! 15111: cmpl r10,$t$smc # jump if no fields left ! 15112: bnequ 0f ! 15113: jmp cmp31 ! 15114: 0: ! 15115: cmpl r10,$t$sgo # jump if s for success goto ! 15116: beqlu cmp14 ! 15117: cmpl r10,$t$fgo # jump if f for failure goto ! 15118: beqlu cmp16 ! 15119: # ! 15120: # HERE FOR UNCONDITIONAL GOTO (I.E. NOT F OR S) ! 15121: # ! 15122: movl sp,scnrs # set to rescan element not f,s ! 15123: jsb scngf # scan out goto field ! 15124: tstl 4*cmfgo(sp) # error if fgoto already ! 15125: bnequ cmp17 ! 15126: movl r9,4*cmfgo(sp) # else set as fgoto ! 15127: jmp cmp15 # merge with sgoto circuit ! 15128: # ! 15129: # HERE FOR SUCCESS GOTO ! 15130: # ! 15131: cmp14: jsb scngf # scan success goto field ! 15132: movl $num01,4*cmcgo(sp) # set conditional goto flag ! 15133: # ! 15134: # UNCONTIONAL GOTO MERGES HERE ! 15135: # ! 15136: cmp15: tstl 4*cmsgo(sp) # error if sgoto already given ! 15137: bnequ cmp17 ! 15138: movl r9,4*cmsgo(sp) # else set sgoto ! 15139: jmp cmp13 # loop back for next goto field ! 15140: # ! 15141: # HERE FOR FAILURE GOTO ! 15142: # ! 15143: cmp16: jsb scngf # scan goto field ! 15144: movl $num01,4*cmcgo(sp) # set conditonal goto flag ! 15145: tstl 4*cmfgo(sp) # error if fgoto already given ! 15146: bnequ cmp17 ! 15147: movl r9,4*cmfgo(sp) # else store fgoto pointer ! 15148: jmp cmp13 # loop back for next field ! 15149: #page ! 15150: # ! 15151: # CMPIL (CONTINUED) ! 15152: # ! 15153: # HERE FOR DUPLICATED GOTO FIELD ! 15154: # ! 15155: cmp17: jmp er_218 # syntax error. duplicated goto field ! 15156: # ! 15157: # HERE TO GENERATE CODE ! 15158: # ! 15159: cmp18: clrl scnse # stop positional error flags ! 15160: movl 4*cmstm(sp),r9 # load tree ptr for statement body ! 15161: clrl r7 # collectable value for wb for cdgvl ! 15162: clrl r8 # reset constant flag for cdgvl ! 15163: jsb expap # test for pattern match ! 15164: .long cmp19 # jump if not pattern match ! 15165: movl $opms$,4*cmopn(r9) # else set pattern match pointer ! 15166: movl $c$pmt,4*cmtyp(r9) ! 15167: # ! 15168: # HERE AFTER DEALING WITH SPECIAL PATTERN MATCH CASE ! 15169: # ! 15170: cmp19: jsb cdgvl # generate code for body of statement ! 15171: movl 4*cmsgo(sp),r9 # load sgoto pointer ! 15172: movl r9,r6 # copy it ! 15173: tstl r9 # jump if no success goto ! 15174: beqlu cmp21 ! 15175: clrl 4*cmsoc(sp) # clear success offset fillin ptr ! 15176: cmpl r9,state # jump if complex goto ! 15177: bgequ cmp20 ! 15178: # ! 15179: # HERE FOR SIMPLE SUCCESS GOTO (LABEL) ! 15180: # ! 15181: addl2 $4*vrtra,r6 # point to vrtra field as required ! 15182: jsb cdwrd # generate success goto ! 15183: jmp cmp22 # jump to deal with fgoto ! 15184: # ! 15185: # HERE FOR COMPLEX SUCCESS GOTO ! 15186: # ! 15187: cmp20: cmpl r9,4*cmfgo(sp) # no code if same as fgoto ! 15188: beqlu cmp22 ! 15189: clrl r7 # else set ok value for cdgvl in wb ! 15190: jsb cdgcg # generate code for success goto ! 15191: jmp cmp22 # jump to deal with fgoto ! 15192: # ! 15193: # HERE FOR NO SUCCESS GOTO ! 15194: # ! 15195: cmp21: movl cwcof,4*cmsoc(sp)# set success fill in offset ! 15196: movl $ocer$,r6 # point to compile error call ! 15197: jsb cdwrd # generate as temporary value ! 15198: #page ! 15199: # ! 15200: # CMPIL (CONTINUED) ! 15201: # ! 15202: # HERE TO DEAL WITH FAILURE GOTO ! 15203: # ! 15204: cmp22: movl 4*cmfgo(sp),r9 # load failure goto pointer ! 15205: movl r9,r6 # copy it ! 15206: clrl 4*cmffc(sp) # set no fill in required yet ! 15207: tstl r9 # jump if no failure goto given ! 15208: beqlu cmp23 ! 15209: addl2 $4*vrtra,r6 # point to vrtra field in case ! 15210: cmpl r9,state # jump to gen if simple fgoto ! 15211: blequ cmpse ! 15212: # ! 15213: # HERE FOR COMPLEX FAILURE GOTO ! 15214: # ! 15215: movl cwcof,r7 # save offset to o$gof call ! 15216: movl $ogof$,r6 # point to failure goto call ! 15217: jsb cdwrd # generate ! 15218: movl $ofif$,r6 # point to fail in fail word ! 15219: jsb cdwrd # generate ! 15220: jsb cdgcg # generate code for failure goto ! 15221: movl r7,r6 # copy offset to o$gof for cdfal ! 15222: movl $b$cdc,r7 # set complex case cdtyp ! 15223: jmp cmp25 # jump to build cdblk ! 15224: # ! 15225: # HERE IF NO FAILURE GOTO GIVEN ! 15226: # ! 15227: cmp23: movl $ounf$,r6 # load unexpected failure call in cas ! 15228: movl cswfl,r8 # get -nofail flag ! 15229: bisl2 4*cmcgo(sp),r8 # check if conditional goto ! 15230: tstl r8 # jump if -nofail and no cond. goto ! 15231: beqlu cmpse ! 15232: movl sp,4*cmffc(sp) # else set fill in flag ! 15233: movl $ocer$,r6 # and set compile error for temporary ! 15234: # ! 15235: # MERGE HERE WITH CDFAL VALUE IN WA, SIMPLE CDBLK ! 15236: # ALSO SPECIAL ENTRY AFTER STATEMENT ERROR ! 15237: # ! 15238: cmpse: movl $b$cds,r7 # set cdtyp for simple case ! 15239: #page ! 15240: # ! 15241: # CMPIL (CONTINUED) ! 15242: # ! 15243: # MERGE HERE TO BUILD CDBLK ! 15244: # ! 15245: # (WA) CDFAL VALUE TO BE GENERATED ! 15246: # (WB) CDTYP VALUE TO BE GENERATED ! 15247: # ! 15248: # AT THIS STAGE, WE CHOP OFF AN APPROPRIATE CHUNK OF THE ! 15249: # CURRENT CCBLK AND CONVERT IT INTO A CDBLK. THE REMAINDER ! 15250: # OF THE CCBLK IS REFORMATTED TO BE THE NEW CCBLK. ! 15251: # ! 15252: cmp25: movl r$ccb,r9 # point to ccblk ! 15253: movl 4*cmlbl(sp),r10 # get possible label pointer ! 15254: tstl r10 # skip if no label ! 15255: beqlu cmp26 ! 15256: clrl 4*cmlbl(sp) # clear flag for next statement ! 15257: movl r9,4*vrlbl(r10) # put cdblk ptr in vrblk label field ! 15258: # ! 15259: # MERGE AFTER DOING LABEL ! 15260: # ! 15261: cmp26: movl r7,(r9) # set type word for new cdblk ! 15262: movl r6,4*cdfal(r9) # set failure word ! 15263: movl r9,r10 # copy pointer to ccblk ! 15264: movl 4*ccuse(r9),r7 # load length gen (= new cdlen) ! 15265: movl 4*cclen(r9),r8 # load total ccblk length ! 15266: addl2 r7,r10 # point past cdblk ! 15267: subl2 r7,r8 # get length left for chop off ! 15268: movl $b$cct,(r10) # set type code for new ccblk at end ! 15269: movl $4*cccod,4*ccuse(r10) # set initial code offset ! 15270: movl $4*cccod,cwcof # reinitialise cwcof ! 15271: movl r8,4*cclen(r10) # set new length ! 15272: movl r10,r$ccb # set new ccblk pointer ! 15273: movl cmpsn,4*cdstm(r9)# set statement number ! 15274: incl cmpsn # bump statement number ! 15275: # ! 15276: # SET POINTERS IN PREVIOUS CODE BLOCK AS REQUIRED ! 15277: # ! 15278: movl 4*cmpcd(sp),r10 # load ptr to previous cdblk ! 15279: tstl 4*cmffp(sp) # jump if no failure fill in required ! 15280: beqlu cmp27 ! 15281: movl r9,4*cdfal(r10) # else set failure ptr in previous ! 15282: # ! 15283: # HERE TO DEAL WITH SUCCESS FORWARD POINTER ! 15284: # ! 15285: cmp27: movl 4*cmsop(sp),r6 # load success offset ! 15286: tstl r6 # jump if no fill in required ! 15287: beqlu cmp28 ! 15288: addl2 r6,r10 # else point to fill in location ! 15289: movl r9,(r10) # store forward pointer ! 15290: clrl r10 # clear garbage xl value ! 15291: #page ! 15292: # ! 15293: # CMPIL (CONTINUED) ! 15294: # ! 15295: # NOW SET FILL IN POINTERS FOR THIS STATEMENT ! 15296: # ! 15297: cmp28: movl 4*cmffc(sp),4*cmffp(sp) # copy failure fill in flag ! 15298: movl 4*cmsoc(sp),4*cmsop(sp) # copy success fill in offset ! 15299: movl r9,4*cmpcd(sp) # save ptr to this cdblk ! 15300: tstl 4*cmtra(sp) # jump if initial entry already set ! 15301: bnequ cmp29 ! 15302: movl r9,4*cmtra(sp) # else set ptr here as default ! 15303: # ! 15304: # HERE AFTER COMPILING ONE STATEMENT ! 15305: # ! 15306: cmp29: cmpl stage,$stgce # jump if not end line just done ! 15307: bgequ 0f ! 15308: jmp cmp01 ! 15309: 0: ! 15310: tstl cswls # skip if -nolist ! 15311: beqlu cmp30 ! 15312: jsb listr # list last line ! 15313: # ! 15314: # RETURN ! 15315: # ! 15316: cmp30: movl 4*cmtra(sp),r9 # load initial entry cdblk pointer ! 15317: addl2 $4*cmnen,sp # pop work locations off stack ! 15318: rsb # and return to cmpil caller ! 15319: # ! 15320: # HERE AT END OF GOTO FIELD ! 15321: # ! 15322: cmp31: movl 4*cmfgo(sp),r7 # get fail goto ! 15323: bisl2 4*cmsgo(sp),r7 # or in success goto ! 15324: tstl r7 # ok if non-null field ! 15325: beqlu 0f ! 15326: jmp cmp18 ! 15327: 0: ! 15328: jmp er_219 # syntax error. empty goto field ! 15329: # ! 15330: # CONTROL CARD FOUND ! 15331: # ! 15332: cmp32: incl r7 # point past ch$mn ! 15333: jsb cncrd # process control card ! 15334: clrl scnse # clear start of element loc. ! 15335: jmp cmpce # loop for next statement ! 15336: #enp # end procedure cmpil ! 15337: #page ! 15338: # ! 15339: # CNCRD -- CONTROL CARD PROCESSOR ! 15340: # ! 15341: # CALLED TO DEAL WITH CONTROL CARDS ! 15342: # ! 15343: # R$CIM POINTS TO CURRENT IMAGE ! 15344: # (WB) OFFSET TO 1ST CHAR OF CONTROL CARD ! 15345: # JSR CNCRD CALL TO PROCESS CONTROL CARDS ! 15346: # (XL,XR,WA,WB,WC,IA) DESTROYED ! 15347: # ! 15348: cncrd: #prc # entry point ! 15349: movl r7,scnpt # offset for control card scan ! 15350: movl $ccnoc,r6 # number of chars for comparison ! 15351: movab 3+(4*0)(r6),r6 # convert to word count ! 15352: ashl $-2,r6,r6 ! 15353: movl r6,cnswc # save word count ! 15354: # ! 15355: # LOOP HERE IF MORE THAN ONE CONTROL CARD ! 15356: # ! 15357: cnc01: cmpl scnpt,scnil # return if end of image ! 15358: blssu 0f ! 15359: jmp cnc09 ! 15360: 0: ! 15361: movl r$cim,r9 # point to image ! 15362: movl scnpt,r11 # [get in scratch register] ! 15363: movab cfp$f(r9)[r11],r9# char ptr for first char ! 15364: movzbl (r9)+,r6 # get first char ! 15365: bicl2 $ch$bl,r6 # fold to upper case ! 15366: cmpl r6,$ch$li # special case of -inxxx ! 15367: bnequ 0f ! 15368: jmp cnc07 ! 15369: 0: ! 15370: movl sp,scncc # set flag for scane ! 15371: jsb scane # scan card name ! 15372: clrl scncc # clear scane flag ! 15373: tstl r10 # fail unless control card name ! 15374: beqlu 0f ! 15375: jmp cnc06 ! 15376: 0: ! 15377: movl $ccnoc,r6 # no. of chars to be compared ! 15378: cmpl 4*sclen(r9),r6 # fail if too few chars ! 15379: bgequ 0f ! 15380: jmp cnc06 ! 15381: 0: ! 15382: movl r9,r10 # point to control card name ! 15383: clrl r7 # zero offset for substring ! 15384: jsb sbstr # extract substring for comparison ! 15385: movl 4*sclen(r9),r6 # reload length ! 15386: jsb flstg # fold to upper case ! 15387: movl r9,cnscc # keep control card substring ptr ! 15388: movl $ccnms,r9 # point to list of standard names ! 15389: clrl r7 # initialise name offset ! 15390: movl $cc$nc,r8 # number of standard names ! 15391: # ! 15392: # TRY TO MATCH NAME ! 15393: # ! 15394: cnc02: movl cnscc,r10 # point to name ! 15395: movl cnswc,r6 # counter for inner loop ! 15396: jmp cnc04 # jump into loop ! 15397: # ! 15398: # INNER LOOP TO MATCH CARD NAME CHARS ! 15399: # ! 15400: cnc03: addl2 $4,r9 # bump standard names ptr ! 15401: addl2 $4,r10 # bump name pointer ! 15402: # ! 15403: # HERE TO INITIATE THE LOOP ! 15404: # ! 15405: cnc04: cmpl 4*schar(r10),(r9)# comp. up to cfp$c chars at once ! 15406: bnequ cnc05 ! 15407: sobgtr r6,cnc03 # loop if more words to compare ! 15408: #page ! 15409: # ! 15410: # CNCRD (CONTINUED) ! 15411: # ! 15412: # MATCHED - BRANCH ON CARD OFFSET ! 15413: # ! 15414: movl r7,r10 # get name offset ! 15415: casel r10,$0,$cc$nc # switch ! 15416: 5: ! 15417: .word cnc37-5b # -case ! 15418: .word cnc10-5b # -double ! 15419: .word cnc11-5b # -dump ! 15420: .word cnc12-5b # -eject ! 15421: .word cnc13-5b # -errors ! 15422: .word cnc14-5b # -execute ! 15423: .word cnc15-5b # -fail ! 15424: .word cnc16-5b # -list ! 15425: .word cnc17-5b # -noerrors ! 15426: .word cnc18-5b # -noexecute ! 15427: .word cnc19-5b # -nofail ! 15428: .word cnc20-5b # -nolist ! 15429: .word cnc21-5b # -noopt ! 15430: .word cnc22-5b # -noprint ! 15431: .word cnc24-5b # -optimise ! 15432: .word cnc25-5b # -print ! 15433: .word cnc27-5b # -single ! 15434: .word cnc28-5b # -space ! 15435: .word cnc31-5b # -stitle ! 15436: .word cnc32-5b # -title ! 15437: .word cnc36-5b # -trace ! 15438: #esw # end switch ! 15439: # ! 15440: # NOT MATCHED YET. ALIGN STD NAMES PTR AND TRY AGAIN ! 15441: # ! 15442: cnc05: addl2 $4,r9 # bump standard names ptr ! 15443: sobgtr r6,cnc05 # loop ! 15444: incl r7 # bump names offset ! 15445: sobgtr r8,cnc02 # continue if more names ! 15446: # ! 15447: # INVALID CONTROL CARD NAME ! 15448: # ! 15449: cnc06: jmp er_247 # invalid control card ! 15450: # ! 15451: # SPECIAL PROCESSING FOR -INXXX ! 15452: # ! 15453: cnc07: movzbl (r9),r6 # get next char ! 15454: bicl2 $ch$bl,r6 # fold to upper case ! 15455: cmpl r6,$ch$ln # fail if not letter n ! 15456: beqlu 0f ! 15457: jmp cnc06 ! 15458: 0: ! 15459: addl2 $num02,scnpt # bump offset past -in ! 15460: jsb scane # scan integer after -in ! 15461: movl r9,-(sp) # stack scanned item ! 15462: jsb gtsmi # check if integer ! 15463: .long cnc06 # fail if not integer ! 15464: .long cnc06 # fail if negative or large ! 15465: movl r9,cswin # keep integer ! 15466: #page ! 15467: # ! 15468: # CNCRD (CONTINUED) ! 15469: # ! 15470: # CHECK FOR MORE CONTROL CARDS BEFORE RETURNING ! 15471: # ! 15472: cnc08: movl scnpt,r6 # preserve in case xeq time compile ! 15473: jsb scane # look for comma ! 15474: cmpl r10,$t$cma # loop if comma found ! 15475: bnequ 0f ! 15476: jmp cnc01 ! 15477: 0: ! 15478: movl r6,scnpt # restore scnpt in case xeq time ! 15479: # ! 15480: # RETURN POINT ! 15481: # ! 15482: cnc09: rsb # return ! 15483: # ! 15484: # -DOUBLE ! 15485: # ! 15486: cnc10: movl sp,cswdb # set switch ! 15487: jmp cnc08 # merge ! 15488: # ! 15489: # -DUMP ! 15490: # THIS IS USED FOR SYSTEM DEBUGGING . IT HAS THE EFFECT OF ! 15491: # PRODUCING A CORE DUMP AT COMPILATION TIME ! 15492: # ! 15493: cnc11: jsb sysdm # call dumper ! 15494: jmp cnc09 # finished ! 15495: # ! 15496: # -EJECT ! 15497: # ! 15498: cnc12: tstl cswls # return if -nolist ! 15499: bnequ 0f ! 15500: jmp cnc09 ! 15501: 0: ! 15502: jsb prtps # eject ! 15503: jsb listt # list title ! 15504: jmp cnc09 # finished ! 15505: # ! 15506: # -ERRORS ! 15507: # ! 15508: cnc13: clrl cswer # clear switch ! 15509: jmp cnc08 # merge ! 15510: # ! 15511: # -EXECUTE ! 15512: # ! 15513: cnc14: clrl cswex # clear switch ! 15514: jmp cnc08 # merge ! 15515: # ! 15516: # -FAIL ! 15517: # ! 15518: cnc15: movl sp,cswfl # set switch ! 15519: jmp cnc08 # merge ! 15520: # ! 15521: # -LIST ! 15522: # ! 15523: cnc16: movl sp,cswls # set switch ! 15524: cmpl stage,$stgic # done if compile time ! 15525: beqlu cnc08 ! 15526: # ! 15527: # LIST CODE LINE IF EXECUTE TIME COMPILE ! 15528: # ! 15529: clrl lstpf # permit listing ! 15530: jsb listr # list line ! 15531: jmp cnc08 # merge ! 15532: #page ! 15533: # ! 15534: # CNCRD (CONTINUED) ! 15535: # ! 15536: # -NOERRORS ! 15537: # ! 15538: cnc17: movl sp,cswer # set switch ! 15539: jmp cnc08 # merge ! 15540: # ! 15541: # -NOEXECUTE ! 15542: # ! 15543: cnc18: movl sp,cswex # set switch ! 15544: jmp cnc08 # merge ! 15545: # ! 15546: # -NOFAIL ! 15547: # ! 15548: cnc19: clrl cswfl # clear switch ! 15549: jmp cnc08 # merge ! 15550: # ! 15551: # -NOLIST ! 15552: # ! 15553: cnc20: clrl cswls # clear switch ! 15554: jmp cnc08 # merge ! 15555: # ! 15556: # -NOOPTIMISE ! 15557: # ! 15558: cnc21: movl sp,cswno # set switch ! 15559: jmp cnc08 # merge ! 15560: # ! 15561: # -NOPRINT ! 15562: # ! 15563: cnc22: clrl cswpr # clear switch ! 15564: jmp cnc08 # merge ! 15565: # ! 15566: # -OPTIMISE ! 15567: # ! 15568: cnc24: clrl cswno # clear switch ! 15569: jmp cnc08 # merge ! 15570: # ! 15571: # -PRINT ! 15572: # ! 15573: cnc25: movl sp,cswpr # set switch ! 15574: jmp cnc08 # merge ! 15575: #page ! 15576: # ! 15577: # CNCRD (CONTINUED) ! 15578: # ! 15579: # -SINGLE ! 15580: # ! 15581: cnc27: clrl cswdb # clear switch ! 15582: jmp cnc08 # merge ! 15583: # ! 15584: # -SPACE ! 15585: # ! 15586: cnc28: tstl cswls # return if -nolist ! 15587: bnequ 0f ! 15588: jmp cnc09 ! 15589: 0: ! 15590: jsb scane # scan integer after -space ! 15591: movl $num01,r8 # 1 space in case ! 15592: cmpl r9,$t$smc # jump if no integer ! 15593: beqlu cnc29 ! 15594: movl r9,-(sp) # stack it ! 15595: jsb gtsmi # check integer ! 15596: .long cnc06 # fail if not integer ! 15597: .long cnc06 # fail if negative or large ! 15598: tstl r8 # jump if non zero ! 15599: bnequ cnc29 ! 15600: movl $num01,r8 # else 1 space ! 15601: # ! 15602: # MERGE WITH COUNT OF LINES TO SKIP ! 15603: # ! 15604: cnc29: addl2 r8,lstlc # bump line count ! 15605: # convert to loop counter ! 15606: cmpl lstlc,lstnp # jump if fits on page ! 15607: blssu cnc30 ! 15608: jsb prtps # eject ! 15609: jsb listt # list title ! 15610: jmp cnc09 # merge ! 15611: # ! 15612: # SKIP LINES ! 15613: # ! 15614: cnc30: jsb prtnl # print a blank ! 15615: sobgtr r8,cnc30 # loop ! 15616: jmp cnc09 # merge ! 15617: #page ! 15618: # ! 15619: # CNCRD (CONTINUED) ! 15620: # ! 15621: # -STITL ! 15622: # ! 15623: cnc31: movl $r$stl,cnr$t # ptr to r$stl ! 15624: jmp cnc33 # merge ! 15625: # ! 15626: # -TITLE ! 15627: # ! 15628: cnc32: movl $nulls,r$stl # clear subtitle ! 15629: movl $r$ttl,cnr$t # ptr to r$ttl ! 15630: # ! 15631: # COMMON PROCESSING FOR -TITLE, -STITL ! 15632: # ! 15633: cnc33: movl $nulls,r9 # null in case needed ! 15634: movl sp,cnttl # set flag for next listr call ! 15635: movl $ccofs,r7 # offset to title/subtitle ! 15636: movl scnil,r6 # input image length ! 15637: cmpl r6,r7 # jump if no chars left ! 15638: blequ cnc34 ! 15639: subl2 r7,r6 # no of chars to extract ! 15640: movl r$cim,r10 # point to image ! 15641: jsb sbstr # get title/subtitle ! 15642: # ! 15643: # STORE TITLE/SUBTITLE ! 15644: # ! 15645: cnc34: movl cnr$t,r10 # point to storage location ! 15646: movl r9,(r10) # store title/subtitle ! 15647: cmpl r10,$r$stl # return if stitl ! 15648: bnequ 0f ! 15649: jmp cnc09 ! 15650: 0: ! 15651: tstl precl # return if extended listing ! 15652: beqlu 0f ! 15653: jmp cnc09 ! 15654: 0: ! 15655: tstl prich # return if regular printer ! 15656: bnequ 0f ! 15657: jmp cnc09 ! 15658: 0: ! 15659: movl 4*sclen(r9),r10 # get length of title ! 15660: movl r10,r6 # copy it ! 15661: tstl r10 # jump if null ! 15662: beqlu cnc35 ! 15663: addl2 $num10,r10 # increment ! 15664: cmpl r10,prlen # use default lstp0 val if too long ! 15665: blssu 0f ! 15666: jmp cnc09 ! 15667: 0: ! 15668: addl2 $num04,r6 # point just past title ! 15669: # ! 15670: # STORE OFFSET TO PAGE NN MESSAGE FOR SHORT TITLE ! 15671: # ! 15672: cnc35: movl r6,lstpo # store offset ! 15673: jmp cnc09 # return ! 15674: # ! 15675: # -TRACE ! 15676: # PROVIDED FOR SYSTEM DEBUGGING. TOGGLES THE SYSTEM LABEL ! 15677: # TRACE SWITCH AT COMPILE TIME ! 15678: # ! 15679: cnc36: jsb systt # toggle switch ! 15680: jmp cnc08 # merge ! 15681: # ! 15682: # -CASE ! 15683: # SETS VALUE OF KVCAS SO THAT NAMES ARE FOLDED OR NOT ! 15684: # DURING COMPILATION. ! 15685: # ! 15686: cnc37: jsb scane # scan integer after -case ! 15687: clrl r8 # get 0 in case none there ! 15688: cmpl r10,$t$smc # skip if no integer ! 15689: beqlu cnc38 ! 15690: movl r9,-(sp) # stack it ! 15691: jsb gtsmi # check integer ! 15692: .long cnc06 # fail if not integer ! 15693: .long cnc06 # fail if negative or too large ! 15694: cnc38: movl r8,kvcas # store new case value ! 15695: jmp cnc09 # merge ! 15696: #enp # end procedure cncrd ! 15697: #page ! 15698: # ! 15699: # DFFNC -- DEFINE FUNCTION ! 15700: # ! 15701: # DFFNC IS CALLED WHENEVER A NEW FUNCTION IS ASSIGNED TO ! 15702: # A VARIABLE. IT DEALS WITH EXTERNAL FUNCTION USE COUNTS. ! 15703: # ! 15704: # (XR) POINTER TO VRBLK ! 15705: # (XL) POINTER TO NEW FUNCTION BLOCK ! 15706: # JSR DFFNC CALL TO DEFINE FUNCTION ! 15707: # (WA,WB) DESTROYED ! 15708: # ! 15709: dffnc: #prc # entry point ! 15710: cmpl (r10),$b$efc # skip if new function not external ! 15711: bnequ dffn1 ! 15712: incl 4*efuse(r10) # else increment its use count ! 15713: # ! 15714: # HERE AFTER DEALING WITH NEW FUNCTION USE COUNT ! 15715: # ! 15716: dffn1: movl r9,r6 # save vrblk pointer ! 15717: movl 4*vrfnc(r9),r9 # load old function pointer ! 15718: cmpl (r9),$b$efc # jump if old function not external ! 15719: bnequ dffn2 ! 15720: movl 4*efuse(r9),r7 # else get use count ! 15721: decl r7 # decrement ! 15722: movl r7,4*efuse(r9) # store decremented value ! 15723: tstl r7 # jump if use count still non-zero ! 15724: bnequ dffn2 ! 15725: jsb sysul # else call system unload function ! 15726: # ! 15727: # HERE AFTER DEALING WITH OLD FUNCTION USE COUNT ! 15728: # ! 15729: dffn2: movl r6,r9 # restore vrblk pointer ! 15730: movl r10,r6 # copy function block ptr ! 15731: cmpl r9,$r$yyy # skip checks if opsyn op definition ! 15732: blssu dffn3 ! 15733: tstl 4*vrlen(r9) # jump if not system variable ! 15734: bnequ dffn3 ! 15735: # ! 15736: # FOR SYSTEM VARIABLE, CHECK FOR ILLEGAL REDEFINITION ! 15737: # ! 15738: movl 4*vrsvp(r9),r10 # point to svblk ! 15739: movl 4*svbit(r10),r7 # load bit indicators ! 15740: mcoml btfnc,r11 # is it a system function ! 15741: bicl2 r11,r7 ! 15742: tstl r7 # redef ok if not ! 15743: beqlu dffn3 ! 15744: jmp er_248 # attempted redefinition of system function ! 15745: # ! 15746: # HERE IF REDEFINITION IS PERMITTED ! 15747: # ! 15748: dffn3: movl r6,4*vrfnc(r9) # store new function pointer ! 15749: movl r6,r10 # restore function block pointer ! 15750: rsb # return to dffnc caller ! 15751: #enp # end procedure dffnc ! 15752: #page ! 15753: # ! 15754: # DTACH -- DETACH I/O ASSOCIATED NAMES ! 15755: # ! 15756: # DETACHES TRBLKS FROM I/O ASSOCIATED VARIABLES, REMOVES ! 15757: # ENTRY FROM IOCHN CHAIN ATTACHED TO FILEARG1 VRBLK AND MAY ! 15758: # REMOVE VRBLK ACCESS AND STORE TRAPS. ! 15759: # INPUT, OUTPUT, TERMINAL ARE HANDLED SPECIALLY. ! 15760: # ! 15761: # (XL) I/O ASSOC. VBL NAME BASE PTR ! 15762: # (WA) OFFSET TO NAME ! 15763: # JSR DTACH CALL FOR DETACH OPERATION ! 15764: # (XL,XR,WA,WB,WC) DESTROYED ! 15765: # ! 15766: dtach: #prc # entry point ! 15767: movl r10,dtcnb # store name base (gbcol not called) ! 15768: addl2 r6,r10 # point to name location ! 15769: movl r10,dtcnm # store it ! 15770: # ! 15771: # LOOP TO SEARCH FOR I/O TRBLK ! 15772: # ! 15773: dtch1: movl r10,r9 # copy name pointer ! 15774: # ! 15775: # CONTINUE AFTER BLOCK DELETION ! 15776: # ! 15777: dtch2: movl (r10),r10 # point to next value ! 15778: cmpl (r10),$b$trt # jump at chain end ! 15779: bnequ dtch6 ! 15780: movl 4*trtyp(r10),r6 # get trap block type ! 15781: cmpl r6,$trtin # jump if input ! 15782: beqlu dtch3 ! 15783: cmpl r6,$trtou # jump if output ! 15784: beqlu dtch3 ! 15785: addl2 $4*trnxt,r10 # point to next link ! 15786: jmp dtch1 # loop ! 15787: # ! 15788: # DELETE AN OLD ASSOCIATION ! 15789: # ! 15790: dtch3: movl 4*trval(r10),(r9)# delete trblk ! 15791: movl r10,r6 # dump xl ... ! 15792: movl r9,r7 # ... and xr ! 15793: movl 4*trtrf(r10),r10# point to trtrf trap block ! 15794: tstl r10 # jump if no iochn ! 15795: beqlu dtch5 ! 15796: cmpl (r10),$b$trt # jump if input, output, terminal ! 15797: bnequ dtch5 ! 15798: # ! 15799: # LOOP TO SEARCH IOCHN CHAIN FOR NAME PTR ! 15800: # ! 15801: dtch4: movl r10,r9 # remember link ptr ! 15802: movl 4*trtrf(r10),r10# point to next link ! 15803: tstl r10 # jump if end of chain ! 15804: beqlu dtch5 ! 15805: movl 4*ionmb(r10),r8 # get name base ! 15806: addl2 4*ionmo(r10),r8 # add offset ! 15807: cmpl r8,dtcnm # loop if no match ! 15808: bnequ dtch4 ! 15809: movl 4*trtrf(r10),4*trtrf(r9) # remove name from chain ! 15810: #page ! 15811: # ! 15812: # DTACH (CONTINUED) ! 15813: # ! 15814: # PREPARE TO RESUME I/O TRBLK SCAN ! 15815: # ! 15816: dtch5: movl r6,r10 # recover xl ... ! 15817: movl r7,r9 # ... and xr ! 15818: addl2 $4*trval,r10 # point to value field ! 15819: jmp dtch2 # continue ! 15820: # ! 15821: # EXIT POINT ! 15822: # ! 15823: dtch6: movl dtcnb,r9 # possible vrblk ptr ! 15824: jsb setvr # reset vrblk if necessary ! 15825: rsb # return ! 15826: #enp # end procedure dtach ! 15827: #page ! 15828: # ! 15829: # DTYPE -- GET DATATYPE NAME ! 15830: # ! 15831: # (XR) OBJECT WHOSE DATATYPE IS REQUIRED ! 15832: # JSR DTYPE CALL TO GET DATATYPE ! 15833: # (XR) RESULT DATATYPE ! 15834: # ! 15835: dtype: #prc # entry point ! 15836: cmpl (r9),$b$pdt # jump if prog.defined ! 15837: beqlu dtyp1 ! 15838: movl (r9),r9 # load type word ! 15839: movzwl -2(r9),r9 # get entry point id (block code) ! 15840: moval 0[r9],r9 # convert to byte offset ! 15841: movl l^scnmt(r9),r9 # load table entry ! 15842: rsb # exit to dtype caller ! 15843: # ! 15844: # HERE IF PROGRAM DEFINED ! 15845: # ! 15846: dtyp1: movl 4*pddfp(r9),r9 # point to dfblk ! 15847: movl 4*dfnam(r9),r9 # get datatype name from dfblk ! 15848: rsb # return to dtype caller ! 15849: #enp # end procedure dtype ! 15850: #page ! 15851: # ! 15852: # DUMPR -- PRINT DUMP OF STORAGE ! 15853: # ! 15854: # (XR) DUMP ARGUMENT (SEE BELOW) ! 15855: # JSR DUMPR CALL TO PRINT DUMP ! 15856: # (XR,XL) DESTROYED ! 15857: # (WA,WB,WC,RA) DESTROYED ! 15858: # ! 15859: # THE DUMP ARGUMENT HAS THE FOLLOWING SIGNIFICANCE ! 15860: # ! 15861: # DMARG = 0 NO DUMP PRINTED ! 15862: # DMARG = 1 PARTIAL DUMP (NAT VARS, KEYWORDS) ! 15863: # DMARG EQ 2 FULL DUMP (INCL ARRAYS ETC.) ! 15864: # DMARG GE 3 CORE DUMP ! 15865: # ! 15866: # SINCE DUMPR SCRAMBLES STORE, IT IS NOT PERMISSIBLE TO ! 15867: # COLLECT IN MID-DUMP. HENCE A COLLECT IS DONE INITIALLY ! 15868: # AND THEN IF STORE RUNS OUT AN ERROR MESSAGE IS PRODUCED. ! 15869: # ! 15870: dumpr: #prc # entry point ! 15871: tstl r9 # skip dump if argument is zero ! 15872: bnequ 0f ! 15873: jmp dmp28 ! 15874: 0: ! 15875: cmpl r9,$num02 # jump if core dump required ! 15876: blequ 0f ! 15877: jmp dmp29 ! 15878: 0: ! 15879: clrl r10 # clear xl ! 15880: clrl r7 # zero move offset ! 15881: movl r9,dmarg # save dump argument ! 15882: jsb gbcol # collect garbage ! 15883: jsb prtpg # eject printer ! 15884: movl $dmhdv,r9 # point to heading for variables ! 15885: jsb prtst # print it ! 15886: jsb prtnl # terminate print line ! 15887: jsb prtnl # and print a blank line ! 15888: # ! 15889: # FIRST ALL NATURAL VARIABLE BLOCKS (VRBLK) WHOSE VALUES ! 15890: # ARE NON-NULL ARE LINKED IN LEXICAL ORDER USING DMVCH AS ! 15891: # THE CHAIN HEAD AND CHAINING THROUGH THE VRGET FIELDS. ! 15892: # NOTE THAT THIS SCRAMBLES STORE IF THE PROCESS IS ! 15893: # INTERRUPTED BEFORE COMPLETION E.G. BY EXCEEDING TIME OR ! 15894: # PRINT LIMITS. SINCE THE SUBSEQUENT CORE DUMPS AND ! 15895: # FAILURES IF EXECUTION IS RESUMED ARE VERY CONFUSING, THE ! 15896: # EXECUTION TIME ERROR ROUTINE CHECKS FOR THIS EVENT AND ! 15897: # ATTEMPTS AN UNSCRAMBLE. SIMILAR PRECAUTIONS SHOULD BE ! 15898: # OBSERVED IF TRANSLATE TIME DUMPING IS IMPLEMENTED. ! 15899: # ! 15900: clrl dmvch # set null chain to start ! 15901: movl hshtb,r6 # point to hash table ! 15902: # ! 15903: # LOOP THROUGH HEADERS IN HASH TABLE ! 15904: # ! 15905: dmp00: movl r6,r9 # copy hash bucket pointer ! 15906: addl2 $4,r6 # bump pointer ! 15907: subl2 $4*vrnxt,r9 # set offset to merge ! 15908: # ! 15909: # LOOP THROUGH VRBLKS ON ONE CHAIN ! 15910: # ! 15911: dmp01: movl 4*vrnxt(r9),r9 # point to next vrblk on chain ! 15912: tstl r9 # jump if end of this hash chain ! 15913: bnequ 0f ! 15914: jmp dmp09 ! 15915: 0: ! 15916: movl r9,r10 # else copy vrblk pointer ! 15917: #page ! 15918: # ! 15919: # DUMPR (CONTINUED) ! 15920: # ! 15921: # LOOP TO FIND VALUE AND SKIP IF NULL ! 15922: # ! 15923: dmp02: movl 4*vrval(r10),r10# load value ! 15924: cmpl r10,$nulls # loop for next vrblk if null value ! 15925: beqlu dmp01 ! 15926: cmpl (r10),$b$trt # loop back if value is trapped ! 15927: beqlu dmp02 ! 15928: # ! 15929: # NON-NULL VALUE, PREPARE TO SEARCH CHAIN ! 15930: # ! 15931: movl r9,r8 # save vrblk pointer ! 15932: addl2 $4*vrsof,r9 # adjust ptr to be like scblk ptr ! 15933: tstl 4*sclen(r9) # jump if non-system variable ! 15934: bnequ dmp03 ! 15935: movl 4*vrsvo(r9),r9 # else load ptr to name in svblk ! 15936: # ! 15937: # HERE WITH NAME POINTER FOR NEW BLOCK IN XR ! 15938: # ! 15939: dmp03: movl r9,r7 # save pointer to chars ! 15940: movl r6,dmpsv # save hash bucket pointer ! 15941: movl $dmvch,r6 # point to chain head ! 15942: # ! 15943: # LOOP TO SEARCH CHAIN FOR CORRECT INSERTION POINT ! 15944: # ! 15945: dmp04: movl r6,dmpch # save chain pointer ! 15946: movl r6,r10 # copy it ! 15947: movl (r10),r9 # load pointer to next entry ! 15948: tstl r9 # jump if end of chain to insert ! 15949: bnequ 0f ! 15950: jmp dmp08 ! 15951: 0: ! 15952: addl2 $4*vrsof,r9 # else get name ptr for chained vrblk ! 15953: tstl 4*sclen(r9) # jump if not system variable ! 15954: bnequ dmp05 ! 15955: movl 4*vrsvo(r9),r9 # else point to name in svblk ! 15956: # ! 15957: # HERE PREPARE TO COMPARE THE NAMES ! 15958: # ! 15959: # (WA) SCRATCH ! 15960: # (WB) POINTER TO STRING OF ENTERING VRBLK ! 15961: # (WC) POINTER TO ENTERING VRBLK ! 15962: # (XR) POINTER TO STRING OF CURRENT BLOCK ! 15963: # (XL) SCRATCH ! 15964: # ! 15965: dmp05: movl r7,r10 # point to entering vrblk string ! 15966: movl 4*sclen(r10),r6 # load its length ! 15967: movab cfp$f(r10),r10 # point to chars of entering string ! 15968: cmpl r6,4*sclen(r9) # jump if entering length high ! 15969: bgequ dmp06 ! 15970: movab cfp$f(r9),r9 # else point to chars of old string ! 15971: jsb sbcmc # compare, insert if new is llt old ! 15972: .long dmp08 ! 15973: .long dmp07 ! 15974: jmp dmp08 # or if leq (we had shorter length) ! 15975: # ! 15976: # HERE WHEN NEW LENGTH IS LONGER THAN OLD LENGTH ! 15977: # ! 15978: dmp06: movl 4*sclen(r9),r6 # load shorter length ! 15979: movab cfp$f(r9),r9 # point to chars of old string ! 15980: jsb sbcmc # compare, insert if new one low ! 15981: .long dmp08 ! 15982: .long dmp07 ! 15983: #page ! 15984: # ! 15985: # DUMPR (CONTINUED) ! 15986: # ! 15987: # HERE WE MOVE OUT ON THE CHAIN ! 15988: # ! 15989: dmp07: movl dmpch,r10 # copy chain pointer ! 15990: movl (r10),r6 # move to next entry on chain ! 15991: jmp dmp04 # loop back ! 15992: # ! 15993: # HERE AFTER LOCATING THE PROPER INSERTION POINT ! 15994: # ! 15995: dmp08: movl dmpch,r10 # copy chain pointer ! 15996: movl dmpsv,r6 # restore hash bucket pointer ! 15997: movl r8,r9 # restore vrblk pointer ! 15998: movl (r10),4*vrget(r9)# link vrblk to rest of chain ! 15999: movl r9,(r10) # link vrblk into current chain loc ! 16000: jmp dmp01 # loop back for next vrblk ! 16001: # ! 16002: # HERE AFTER PROCESSING ALL VRBLKS ON ONE CHAIN ! 16003: # ! 16004: dmp09: cmpl r6,hshte # loop back if more buckets to go ! 16005: beqlu 0f ! 16006: jmp dmp00 ! 16007: 0: ! 16008: # ! 16009: # LOOP TO GENERATE DUMP OF NATURAL VARIABLE VALUES ! 16010: # ! 16011: dmp10: movl dmvch,r9 # load pointer to next entry on chain ! 16012: tstl r9 # jump if end of chain ! 16013: beqlu dmp11 ! 16014: movl (r9),dmvch # else update chain ptr to next entry ! 16015: jsb setvr # restore vrget field ! 16016: movl r9,r10 # copy vrblk pointer (name base) ! 16017: movl $4*vrval,r6 # set offset for vrblk name ! 16018: jsb prtnv # print name = value ! 16019: jmp dmp10 # loop back till all printed ! 16020: # ! 16021: # PREPARE TO PRINT KEYWORDS ! 16022: # ! 16023: dmp11: jsb prtnl # print blank line ! 16024: jsb prtnl # and another ! 16025: movl $dmhdk,r9 # point to keyword heading ! 16026: jsb prtst # print heading ! 16027: jsb prtnl # end line ! 16028: jsb prtnl # print one blank line ! 16029: movl $vdmkw,r10 # point to list of keyword svblk ptrs ! 16030: #page ! 16031: # ! 16032: # DUMPR (CONTINUED) ! 16033: # ! 16034: # LOOP TO DUMP KEYWORD VALUES ! 16035: # ! 16036: dmp12: movl (r10)+,r9 # load next svblk ptr from table ! 16037: tstl r9 # jump if end of list ! 16038: beqlu dmp13 ! 16039: movl $ch$am,r6 # load ampersand ! 16040: jsb prtch # print ampersand ! 16041: jsb prtst # print keyword name ! 16042: movl 4*svlen(r9),r6 # load name length from svblk ! 16043: movab 3+(4*svchs)(r6),r6 # get length of name ! 16044: bicl2 $3,r6 ! 16045: addl2 r6,r9 # point to svknm field ! 16046: movl (r9),dmpkn # store in dummy kvblk ! 16047: movl $tmbeb,r9 # point to blank-equal-blank ! 16048: jsb prtst # print it ! 16049: movl r10,dmpsv # save table pointer ! 16050: movl $dmpkb,r10 # point to dummy kvblk ! 16051: movl $4*kvvar,r6 # set zero offset ! 16052: jsb acess # get keyword value ! 16053: .long invalid$ # failure is impossible ! 16054: jsb prtvl # print keyword value ! 16055: jsb prtnl # terminate print line ! 16056: movl dmpsv,r10 # restore table pointer ! 16057: jmp dmp12 # loop back till all printed ! 16058: # ! 16059: # HERE AFTER COMPLETING PARTIAL DUMP ! 16060: # ! 16061: dmp13: cmpl dmarg,$num01 # exit if partial dump complete ! 16062: bnequ 0f ! 16063: jmp dmp27 ! 16064: 0: ! 16065: movl dnamb,r9 # else point to first dynamic block ! 16066: # ! 16067: # LOOP THROUGH BLOCKS IN DYNAMIC STORAGE ! 16068: # ! 16069: dmp14: cmpl r9,dnamp # jump if end of used region ! 16070: bnequ 0f ! 16071: jmp dmp27 ! 16072: 0: ! 16073: movl (r9),r6 # else load first word of block ! 16074: cmpl r6,$b$vct # jump if vector ! 16075: beqlu dmp16 ! 16076: cmpl r6,$b$art # jump if array ! 16077: beqlu dmp17 ! 16078: cmpl r6,$b$pdt # jump if program defined ! 16079: beqlu dmp18 ! 16080: cmpl r6,$b$tbt # jump if table ! 16081: beqlu dmp19 ! 16082: cmpl r6,$b$bct # jump if buffer ! 16083: bnequ 0f ! 16084: jmp dmp30 ! 16085: 0: ! 16086: # ! 16087: # MERGE HERE TO MOVE TO NEXT BLOCK ! 16088: # ! 16089: dmp15: jsb blkln # get length of block ! 16090: addl2 r6,r9 # point past this block ! 16091: jmp dmp14 # loop back for next block ! 16092: #page ! 16093: # ! 16094: # DUMPR (CONTINUED) ! 16095: # ! 16096: # HERE FOR VECTOR ! 16097: # ! 16098: dmp16: movl $4*vcvls,r7 # set offset to first value ! 16099: jmp dmp19 # jump to merge ! 16100: # ! 16101: # HERE FOR ARRAY ! 16102: # ! 16103: dmp17: movl 4*arofs(r9),r7 # set offset to arpro field ! 16104: addl2 $4,r7 # bump to get offset to values ! 16105: jmp dmp19 # jump to merge ! 16106: # ! 16107: # HERE FOR PROGRAM DEFINED ! 16108: # ! 16109: dmp18: movl $4*pdfld,r7 # point to values, merge ! 16110: # ! 16111: # HERE FOR TABLE (OTHERS MERGE) ! 16112: # ! 16113: dmp19: tstl 4*idval(r9) # ignore block if zero id value ! 16114: bnequ 0f ! 16115: jmp dmp15 ! 16116: 0: ! 16117: jsb blkln # else get block length ! 16118: movl r9,r10 # copy block pointer ! 16119: movl r6,dmpsv # save length ! 16120: movl r7,r6 # copy offset to first value ! 16121: jsb prtnl # print blank line ! 16122: movl r6,dmpsa # preserve offset ! 16123: jsb prtvl # print block value (for title) ! 16124: movl dmpsa,r6 # recover offset ! 16125: jsb prtnl # end print line ! 16126: cmpl (r9),$b$tbt # jump if table ! 16127: beqlu dmp22 ! 16128: subl2 $4,r6 # point before first word ! 16129: # ! 16130: # LOOP TO PRINT CONTENTS OF ARRAY, VECTOR, OR PROGRAM DEF ! 16131: # ! 16132: dmp20: movl r10,r9 # copy block pointer ! 16133: addl2 $4,r6 # bump offset ! 16134: addl2 r6,r9 # point to next value ! 16135: cmpl r6,dmpsv # exit if end (xr past block) ! 16136: bnequ 0f ! 16137: jmp dmp14 ! 16138: 0: ! 16139: subl2 $4*vrval,r9 # subtract offset to merge into loop ! 16140: # ! 16141: # LOOP TO FIND VALUE AND IGNORE NULLS ! 16142: # ! 16143: dmp21: movl 4*vrval(r9),r9 # load next value ! 16144: cmpl r9,$nulls # loop back if null value ! 16145: beqlu dmp20 ! 16146: cmpl (r9),$b$trt # loop back if trapped ! 16147: beqlu dmp21 ! 16148: jsb prtnv # else print name = value ! 16149: jmp dmp20 # loop back for next field ! 16150: #page ! 16151: # ! 16152: # DUMPR (CONTINUED) ! 16153: # ! 16154: # HERE TO DUMP A TABLE ! 16155: # ! 16156: dmp22: movl $4*tbbuk,r8 # set offset to first bucket ! 16157: movl $4*teval,r6 # set name offset for all teblks ! 16158: # ! 16159: # LOOP THROUGH TABLE BUCKETS ! 16160: # ! 16161: dmp23: movl r10,-(sp) # save tbblk pointer ! 16162: addl2 r8,r10 # point to next bucket header ! 16163: addl2 $4,r8 # bump bucket offset ! 16164: subl2 $4*tenxt,r10 # subtract offset to merge into loop ! 16165: # ! 16166: # LOOP TO PROCESS TEBLKS ON ONE CHAIN ! 16167: # ! 16168: dmp24: movl 4*tenxt(r10),r10# point to next teblk ! 16169: cmpl r10,(sp) # jump if end of chain ! 16170: beqlu dmp26 ! 16171: movl r10,r9 # else copy teblk pointer ! 16172: # ! 16173: # LOOP TO FIND VALUE AND IGNORE IF NULL ! 16174: # ! 16175: dmp25: movl 4*teval(r9),r9 # load next value ! 16176: cmpl r9,$nulls # ignore if null value ! 16177: beqlu dmp24 ! 16178: cmpl (r9),$b$trt # loop back if trapped ! 16179: beqlu dmp25 ! 16180: movl r8,dmpsv # else save offset pointer ! 16181: jsb prtnv # print name = value ! 16182: movl dmpsv,r8 # reload offset ! 16183: jmp dmp24 # loop back for next teblk ! 16184: # ! 16185: # HERE TO MOVE TO NEXT HASH CHAIN ! 16186: # ! 16187: dmp26: movl (sp)+,r10 # restore tbblk pointer ! 16188: cmpl r8,4*tblen(r10) # loop back if more buckets to go ! 16189: bnequ dmp23 ! 16190: movl r10,r9 # else copy table pointer ! 16191: addl2 r8,r9 # point to following block ! 16192: jmp dmp14 # loop back to process next block ! 16193: # ! 16194: # HERE AFTER COMPLETING DUMP ! 16195: # ! 16196: dmp27: jsb prtpg # eject printer ! 16197: # ! 16198: # MERGE HERE IF NO DUMP GIVEN (DMARG=0) ! 16199: # ! 16200: dmp28: rsb # return to dump caller ! 16201: # ! 16202: # CALL SYSTEM CORE DUMP ROUTINE ! 16203: # ! 16204: dmp29: jsb sysdm # call it ! 16205: jmp dmp28 # return ! 16206: #page ! 16207: # ! 16208: # DUMPR (CONTINUED) ! 16209: # ! 16210: # HERE TO DUMP BUFFER BLOCK ! 16211: # ! 16212: dmp30: jsb prtnl # print blank line ! 16213: jsb prtvl # print value id for title ! 16214: jsb prtnl # force new line ! 16215: movl $ch$dq,r6 # load double quote ! 16216: jsb prtch # print it ! 16217: movl 4*bclen(r9),r8 # load defined length ! 16218: tstl r8 # skip characters if none ! 16219: beqlu dmp32 ! 16220: # load count for loop ! 16221: movl r9,r7 # save bcblk ptr ! 16222: movl 4*bcbuf(r9),r9 # point to bfblk ! 16223: movab cfp$f(r9),r9 # get set to load characters ! 16224: # ! 16225: # LOOP HERE STUFFING CHARACTERS IN OUTPUT STREAM ! 16226: # ! 16227: dmp31: movzbl (r9)+,r6 # get next character ! 16228: jsb prtch # stuff it ! 16229: sobgtr r8,dmp31 # branch for next one ! 16230: movl r7,r9 # restore bcblk pointer ! 16231: # ! 16232: # MERGE TO STUFF CLOSING QUOTE MARK ! 16233: # ! 16234: dmp32: movl $ch$dq,r6 # stuff quote ! 16235: jsb prtch # print it ! 16236: jsb prtnl # print new line ! 16237: movl (r9),r6 # get first wd for blkln ! 16238: jmp dmp15 # merge to get next block ! 16239: #enp # end procedure dumpr ! 16240: #page ! 16241: # ! 16242: # ERMSG -- PRINT ERROR CODE AND ERROR MESSAGE ! 16243: # ! 16244: # KVERT ERROR CODE ! 16245: # JSR ERMSG CALL TO PRINT MESSAGE ! 16246: # (XR,XL,WA,WB,WC,IA) DESTROYED ! 16247: # ! 16248: ermsg: #prc # entry point ! 16249: jsb prtis # print error ptr or blank line ! 16250: movl kvert,r6 # load error code ! 16251: movl $ermms,r9 # point to error message /error/ ! 16252: jsb prtst # print it ! 16253: jsb ertex # get error message text ! 16254: addl2 $thsnd,r6 # bump error code for print ! 16255: movl r6,r5 # fail code in int acc ! 16256: jsb prtin # print code (now have error1xxx) ! 16257: movl prbuf,r10 # point to print buffer ! 16258: movl $num05,r11 # [get in scratch register] ! 16259: movab cfp$f(r10)[r11],r10 # point to the 1 ! 16260: movl $ch$bl,r6 # load a blank ! 16261: movb r6,(r10) # store blank over 1 (error xxx) ! 16262: #csc r10 # complete store characters ! 16263: clrl r10 # clear garbage pointer in xl ! 16264: movl r9,r6 # keep error text ! 16265: movl $ermns,r9 # point to / -- / ! 16266: jsb prtst # print it ! 16267: movl r6,r9 # get error text again ! 16268: jsb prtst # print error message text ! 16269: jsb prtis # print line ! 16270: jsb prtis # print blank line ! 16271: rsb # return to ermsg caller ! 16272: #enp # end procedure ermsg ! 16273: #page ! 16274: # ! 16275: # ERTEX -- GET ERROR MESSAGE TEXT ! 16276: # ! 16277: # (WA) ERROR CODE ! 16278: # JSR ERTEX CALL TO GET ERROR TEXT ! 16279: # (XR) PTR TO ERROR TEXT IN DYNAMIC ! 16280: # (R$ETX) COPY OF PTR TO ERROR TEXT ! 16281: # (XL,WC,IA) DESTROYED ! 16282: # ! 16283: ertex: #prc # entry point ! 16284: movl r6,ertwa # save wa ! 16285: movl r7,ertwb # save wb ! 16286: jsb sysem # get failure message text ! 16287: movl r9,r10 # copy pointer to it ! 16288: movl 4*sclen(r9),r6 # get length of string ! 16289: tstl r6 # jump if null ! 16290: beqlu ert02 ! 16291: clrl r7 # offset of zero ! 16292: jsb sbstr # copy into dynamic store ! 16293: movl r9,r$etx # store for relocation ! 16294: # ! 16295: # RETURN ! 16296: # ! 16297: ert01: movl ertwb,r7 # restore wb ! 16298: movl ertwa,r6 # restore wa ! 16299: rsb # return to caller ! 16300: # ! 16301: # RETURN ERRTEXT CONTENTS INSTEAD OF NULL ! 16302: # ! 16303: ert02: movl r$etx,r9 # get errtext ! 16304: jmp ert01 # return ! 16305: #enp ! 16306: #page ! 16307: # ! 16308: # EVALI -- EVALUATE INTEGER ARGUMENT ! 16309: # ! 16310: # EVALI IS USED BY PATTERN PRIMITIVES LEN,TAB,RTAB,POS,RPOS ! 16311: # WHEN THEIR ARGUMENT IS AN EXPRESSION VALUE. ! 16312: # ! 16313: # (XR) NODE POINTER ! 16314: # (WB) CURSOR ! 16315: # JSR EVALI CALL TO EVALUATE INTEGER ! 16316: # PPM LOC TRANSFER LOC FOR NON-INTEGER ARG ! 16317: # PPM LOC TRANSFER LOC FOR OUT OF RANGE ARG ! 16318: # PPM LOC TRANSFER LOC FOR EVALUATION FAILURE ! 16319: # PPM LOC TRANSFER LOC FOR SUCCESSFUL EVAL ! 16320: # (THE NORMAL RETURN IS NEVER TAKEN) ! 16321: # (XR) PTR TO NODE WITH INTEGER ARGUMENT ! 16322: # (WC,XL,RA) DESTROYED ! 16323: # ! 16324: # ON RETURN, THE NODE POINTED TO HAS THE INTEGER ARGUMENT ! 16325: # IN PARM1 AND THE PROPER SUCCESSOR POINTER IN PTHEN. ! 16326: # THIS ALLOWS MERGING WITH THE NORMAL (INTEGER ARG) CASE. ! 16327: # ! 16328: evali: #prc # entry point (recursive) ! 16329: jsb evalp # evaluate expression ! 16330: .long evli1 # jump on failure ! 16331: movl r10,-(sp) # stack result for gtsmi ! 16332: movl 4*pthen(r9),r10 # load successor pointer ! 16333: jsb gtsmi # convert arg to small integer ! 16334: .long evli2 # jump if not integer ! 16335: .long evli3 # jump if out of range ! 16336: movl r9,evliv # store result in special dummy node ! 16337: movl r10,evlis # store successor pointer ! 16338: movl $evlin,r9 # point to dummy node with result ! 16339: addl3 $4*3,(sp)+,r11 # take successful exit ! 16340: jmp *(r11)+ ! 16341: # ! 16342: # HERE IF EVALUATION FAILS ! 16343: # ! 16344: evli1: addl3 $4*2,(sp)+,r11 # take failure return ! 16345: jmp *(r11)+ ! 16346: # ! 16347: # HERE IF ARGUMENT IS NOT INTEGER ! 16348: # ! 16349: evli2: movl (sp)+,r11 # take non-integer error exit ! 16350: jmp *(r11)+ ! 16351: # ! 16352: # HERE IF ARGUMENT IS OUT OF RANGE ! 16353: # ! 16354: evli3: addl3 $4*1,(sp)+,r11 # take out-of-range error exit ! 16355: jmp *(r11)+ ! 16356: #enp # end procedure evali ! 16357: #page ! 16358: # ! 16359: # EVALP -- EVALUATE EXPRESSION DURING PATTERN MATCH ! 16360: # ! 16361: # EVALP IS USED TO EVALUATE AN EXPRESSION (BY VALUE) DURING ! 16362: # A PATTERN MATCH. THE EFFECT IS LIKE EVALX, BUT PATTERN ! 16363: # VARIABLES ARE STACKED AND RESTORED IF NECESSARY. ! 16364: # ! 16365: # EVALP ALSO DIFFERS FROM EVALX IN THAT IF THE RESULT IS ! 16366: # AN EXPRESSION IT IS REEVALUATED. THIS OCCURS REPEATEDLY. ! 16367: # ! 16368: # (XR) NODE POINTER ! 16369: # (WB) PATTERN MATCH CURSOR ! 16370: # JSR EVALP CALL TO EVALUATE EXPRESSION ! 16371: # PPM LOC TRANSFER LOC IF EVALUATION FAILS ! 16372: # (XL) RESULT ! 16373: # (WA) FIRST WORD OF RESULT BLOCK ! 16374: # (XR,WB) DESTROYED (FAILURE CASE ONLY) ! 16375: # (WC,RA) DESTROYED ! 16376: # ! 16377: # THE EXPRESSION POINTER IS STORED IN PARM1 OF THE NODE ! 16378: # ! 16379: # CONTROL RETURNS TO FAILP ON FAILURE OF EVALUATION ! 16380: # ! 16381: evalp: #prc # entry point (recursive) ! 16382: movl 4*parm1(r9),r10 # load expression pointer ! 16383: cmpl (r10),$b$exl # jump if exblk case ! 16384: beqlu evlp1 ! 16385: # ! 16386: # HERE FOR CASE OF SEBLK ! 16387: # ! 16388: # WE CAN GIVE A FAST RETURN IF THE VALUE OF THE VRBLK IS ! 16389: # NOT AN EXPRESSION AND IS NOT TRAPPED. ! 16390: # ! 16391: movl 4*sevar(r10),r10# load vrblk pointer ! 16392: movl 4*vrval(r10),r10# load value of vrblk ! 16393: movl (r10),r6 # load first word of value ! 16394: cmpl r6,$b$t$$ # jump if not seblk, trblk or exblk ! 16395: bgequ evlp3 ! 16396: # ! 16397: # HERE FOR EXBLK OR SEBLK WITH EXPR VALUE OR TRAPPED VALUE ! 16398: # ! 16399: evlp1: movl r9,-(sp) # stack node pointer ! 16400: movl r7,-(sp) # stack cursor ! 16401: movl r$pms,-(sp) # stack subject string pointer ! 16402: movl pmssl,-(sp) # stack subject string length ! 16403: movl pmdfl,-(sp) # stack dot flag ! 16404: movl pmhbs,-(sp) # stack history stack base pointer ! 16405: movl 4*parm1(r9),r9 # load expression pointer ! 16406: #page ! 16407: # ! 16408: # EVALP (CONTINUED) ! 16409: # ! 16410: # LOOP BACK HERE TO REEVALUATE EXPRESSION RESULT ! 16411: # ! 16412: evlp2: clrl r7 # set flag for by value ! 16413: jsb evalx # evaluate expression ! 16414: .long evlp4 # jump on failure ! 16415: movl (r9),r6 # else load first word of value ! 16416: cmpl r6,$b$e$$ # loop back to reevaluate expression ! 16417: blequ evlp2 ! 16418: # ! 16419: # HERE TO RESTORE PATTERN VALUES AFTER SUCCESSFUL EVAL ! 16420: # ! 16421: movl r9,r10 # copy result pointer ! 16422: movl (sp)+,pmhbs # restore history stack base pointer ! 16423: movl (sp)+,pmdfl # restore dot flag ! 16424: movl (sp)+,pmssl # restore subject string length ! 16425: movl (sp)+,r$pms # restore subject string pointer ! 16426: movl (sp)+,r7 # restore cursor ! 16427: movl (sp)+,r9 # restore node pointer ! 16428: # ! 16429: # COMMON EXIT POINT ! 16430: # ! 16431: evlp3: addl2 $4*1,(sp) # return to evalp caller ! 16432: rsb ! 16433: # ! 16434: # HERE FOR FAILURE DURING EVALUATION ! 16435: # ! 16436: evlp4: movl (sp)+,pmhbs # restore history stack base pointer ! 16437: movl (sp)+,pmdfl # restore dot flag ! 16438: movl (sp)+,pmssl # restore subject string length ! 16439: movl (sp)+,r$pms # restore subject string pointer ! 16440: addl2 $4*num02,sp # remove node ptr, cursor ! 16441: movl (sp)+,r11 # take failure exit ! 16442: jmp *(r11)+ ! 16443: #enp # end procedure evalp ! 16444: #page ! 16445: # ! 16446: # EVALS -- EVALUATE STRING ARGUMENT ! 16447: # ! 16448: # EVALS IS USED BY SPAN, ANY, NOTANY, BREAK, BREAKX WHEN ! 16449: # THEY ARE PASSED AN EXPRESSION ARGUMENT. ! 16450: # ! 16451: # (XR) NODE POINTER ! 16452: # (WB) CURSOR ! 16453: # JSR EVALS CALL TO EVALUATE STRING ! 16454: # PPM LOC TRANSFER LOC FOR NON-STRING ARG ! 16455: # PPM LOC TRANSFER LOC FOR EVALUATION FAILURE ! 16456: # PPM LOC TRANSFER LOC FOR SUCCESSFUL EVAL ! 16457: # (THE NORMAL RETURN IS NEVER TAKEN) ! 16458: # (XR) PTR TO NODE WITH PARMS SET ! 16459: # (XL,WC,RA) DESTROYED ! 16460: # ! 16461: # ON RETURN, THE NODE POINTED TO HAS A CHARACTER TABLE ! 16462: # POINTER IN PARM1 AND A BIT MASK IN PARM2. THE PROPER ! 16463: # SUCCESSOR IS STORED IN PTHEN OF THIS NODE. THUS IT IS ! 16464: # OK FOR MERGING WITH THE NORMAL (MULTI-CHAR STRING) CASE. ! 16465: # ! 16466: evals: #prc # entry point (recursive) ! 16467: jsb evalp # evaluate expression ! 16468: .long evls1 # jump if evaluation fails ! 16469: movl 4*pthen(r9),-(sp)# save successor pointer ! 16470: movl r7,-(sp) # save cursor ! 16471: movl r10,-(sp) # stack result ptr for patst ! 16472: clrl r7 # dummy pcode for one char string ! 16473: clrl r8 # dummy pcode for expression arg ! 16474: movl $p$brk,r10 # appropriate pcode for our use ! 16475: jsb patst # call routine to build node ! 16476: .long evls2 # jump if not string ! 16477: movl (sp)+,r7 # restore cursor ! 16478: movl (sp)+,4*pthen(r9)# store successor pointer ! 16479: addl3 $4*2,(sp)+,r11 # take success return ! 16480: jmp *(r11)+ ! 16481: # ! 16482: # HERE IF EVALUATION FAILS ! 16483: # ! 16484: evls1: addl3 $4*1,(sp)+,r11 # take failure return ! 16485: jmp *(r11)+ ! 16486: # ! 16487: # HERE IF ARGUMENT IS NOT STRING ! 16488: # ! 16489: evls2: addl2 $4*num02,sp # pop successor and cursor ! 16490: movl (sp)+,r11 # take non-string error exit ! 16491: jmp *(r11)+ ! 16492: #enp # end procedure evals ! 16493: #page ! 16494: # ! 16495: # EVALX -- EVALUATE EXPRESSION ! 16496: # ! 16497: # EVALX IS CALLED TO EVALUATE AN EXPRESSION ! 16498: # ! 16499: # (XR) POINTER TO EXBLK OR SEBLK ! 16500: # (WB) 0 IF BY VALUE, 1 IF BY NAME ! 16501: # JSR EVALX CALL TO EVALUATE EXPRESSION ! 16502: # PPM LOC TRANSFER LOC IF EVALUATION FAILS ! 16503: # (XR) RESULT IF CALLED BY VALUE ! 16504: # (XL,WA) RESULT NAME BASE,OFFSET IF BY NAME ! 16505: # (XR) DESTROYED (NAME CASE ONLY) ! 16506: # (XL,WA) DESTROYED (VALUE CASE ONLY) ! 16507: # (WB,WC,RA) DESTROYED ! 16508: # ! 16509: evalx: #prc # entry point, recursive ! 16510: cmpl (r9),$b$exl # jump if exblk case ! 16511: beqlu evlx2 ! 16512: # ! 16513: # HERE FOR SEBLK ! 16514: # ! 16515: movl 4*sevar(r9),r10 # load vrblk pointer (name base) ! 16516: movl $4*vrval,r6 # set name offset ! 16517: tstl r7 # jump if called by name ! 16518: beqlu 0f ! 16519: jmp evlx1 ! 16520: 0: ! 16521: jsb acess # call routine to access value ! 16522: .long evlx9 # jump if failure on access ! 16523: # ! 16524: # MERGE HERE TO EXIT FOR SEBLK CASE ! 16525: # ! 16526: evlx1: addl2 $4*1,(sp) # return to evalx caller ! 16527: rsb ! 16528: #page ! 16529: # ! 16530: # EVALX (CONTINUED) ! 16531: # ! 16532: # HERE FOR FULL EXPRESSION (EXBLK) CASE ! 16533: # ! 16534: # IF AN ERROR OCCURS IN THE EXPRESSION CODE AT EXECUTION ! 16535: # TIME, CONTROL IS PASSED VIA ERROR SECTION TO EXFAL ! 16536: # WITHOUT RETURNING TO THIS ROUTINE. ! 16537: # THE FOLLOWING ENTRIES ARE MADE ON THE STACK BEFORE ! 16538: # GIVING CONTROL TO THE EXPRESSION CODE ! 16539: # ! 16540: # EVALX RETURN POINT ! 16541: # SAVED VALUE OF R$COD ! 16542: # CODE POINTER (-R$COD) ! 16543: # SAVED VALUE OF FLPTR ! 16544: # 0 IF BY VALUE, 1 IF BY NAME ! 16545: # FLPTR --------------- *EXFLC, FAIL OFFSET IN EXBLK ! 16546: # ! 16547: evlx2: movl r3,r8 # get code pointer ! 16548: movl r$cod,r6 # load code block pointer ! 16549: subl2 r6,r8 # get code pointer as offset ! 16550: movl r6,-(sp) # stack old code block pointer ! 16551: movl r8,-(sp) # stack relative code offset ! 16552: movl flptr,-(sp) # stack old failure pointer ! 16553: movl r7,-(sp) # stack name/value indicator ! 16554: movl $4*exflc,-(sp) # stack new fail offset ! 16555: movl flptr,gtcef # keep in case of error ! 16556: movl r$cod,r$gtc # keep code block pointer similarly ! 16557: movl sp,flptr # set new failure pointer ! 16558: movl r9,r$cod # set new code block pointer ! 16559: movl kvstn,4*exstm(r9)# remember stmnt number ! 16560: addl2 $4*excod,r9 # point to first code word ! 16561: movl r9,r3 # set code pointer ! 16562: cmpl stage,$stgxt # jump if not execution time ! 16563: beqlu 0f ! 16564: jmp exits ! 16565: 0: ! 16566: movl $stgee,stage # evaluating expression ! 16567: jmp exits # jump to execute first code word ! 16568: #page ! 16569: # ! 16570: # EVALX (CONTINUED) ! 16571: # ! 16572: # COME HERE IF SUCCESSFUL RETURN BY VALUE (SEE O$RVL) ! 16573: # ! 16574: evlx3: movl (sp)+,r9 # load value ! 16575: tstl 4*1(sp) # jump if called by value ! 16576: beqlu evlx5 ! 16577: jmp er_249 # expression evaluated by name returned value ! 16578: # ! 16579: # HERE FOR EXPRESSION RETURNING BY NAME (SEE O$RNM) ! 16580: # ! 16581: evlx4: movl (sp)+,r6 # load name offset ! 16582: movl (sp)+,r10 # load name base ! 16583: tstl 4*1(sp) # jump if called by name ! 16584: bnequ evlx5 ! 16585: jsb acess # else access value first ! 16586: .long evlx6 # jump if failure during access ! 16587: # ! 16588: # HERE AFTER LOADING CORRECT RESULT INTO XR OR XL,WA ! 16589: # ! 16590: evlx5: clrl r7 # note successful ! 16591: jmp evlx7 # merge ! 16592: # ! 16593: # HERE FOR FAILURE IN EXPRESSION EVALUATION (SEE O$FEX) ! 16594: # ! 16595: evlx6: movl sp,r7 # note unsuccessful ! 16596: # ! 16597: # RESTORE ENVIRONMENT ! 16598: # ! 16599: evlx7: cmpl stage,$stgee # skip if was not previously xt ! 16600: bnequ evlx8 ! 16601: movl $stgxt,stage # execute time ! 16602: # ! 16603: # MERGE WITH STAGE SET UP ! 16604: # ! 16605: evlx8: addl2 $4*num02,sp # pop name/value indicator, *exfal ! 16606: movl (sp)+,flptr # restore old failure pointer ! 16607: movl (sp)+,r8 # load code offset ! 16608: addl2 (sp),r8 # make code pointer absolute ! 16609: movl (sp)+,r$cod # restore old code block pointer ! 16610: movl r8,r3 # restore old code pointer ! 16611: tstl r7 # jump for successful return ! 16612: bnequ 0f ! 16613: jmp evlx1 ! 16614: 0: ! 16615: # ! 16616: # MERGE HERE FOR FAILURE IN SEBLK CASE ! 16617: # ! 16618: evlx9: movl (sp)+,r11 # take failure exit ! 16619: jmp *(r11)+ ! 16620: #enp # end of procedure evalx ! 16621: #page ! 16622: # ! 16623: # EXBLD -- BUILD EXBLK ! 16624: # ! 16625: # EXBLD IS USED TO BUILD AN EXPRESSION BLOCK FROM THE ! 16626: # CODE COMPILED MOST RECENTLY IN THE CURRENT CCBLK. ! 16627: # ! 16628: # (XL) OFFSET IN CCBLK TO START OF CODE ! 16629: # (WB) INTEGER IN RANGE 0 LE N LE MXLEN ! 16630: # JSR EXBLD CALL TO BUILD EXBLK ! 16631: # (XR) PTR TO CONSTRUCTED EXBLK ! 16632: # (WA,WB,XL) DESTROYED ! 16633: # ! 16634: exbld: #prc # entry point ! 16635: movl r10,r6 # copy offset to start of code ! 16636: subl2 $4*excod,r6 # calc reduction in offset in exblk ! 16637: movl r6,-(sp) # stack for later ! 16638: movl cwcof,r6 # load final offset ! 16639: subl2 r10,r6 # compute length of code ! 16640: addl2 $4*exsi$,r6 # add space for standard fields ! 16641: jsb alloc # allocate space for exblk ! 16642: movl r9,-(sp) # save pointer to exblk ! 16643: movl $b$exl,4*extyp(r9) # store type word ! 16644: clrl 4*exstm(r9) # zeroise stmnt number field ! 16645: movl r6,4*exlen(r9) # store length ! 16646: movl $ofex$,4*exflc(r9) # store failure word ! 16647: addl2 $4*exsi$,r9 # set xr for sysmw ! 16648: movl r10,cwcof # reset offset to start of code ! 16649: addl2 r$ccb,r10 # point to start of code ! 16650: subl2 $4*exsi$,r6 # length of code to move ! 16651: movl r6,-(sp) # stack length of code ! 16652: jsb sbmvw # move code to exblk ! 16653: movl (sp)+,r6 # get length of code ! 16654: ashl $-2,r6,r6 # convert byte count to word count ! 16655: # prepare counter for loop ! 16656: movl (sp),r10 # copy exblk ptr, dont unstack ! 16657: addl2 $4*excod,r10 # point to code itself ! 16658: movl 4*1(sp),r7 # get reduction in offset ! 16659: # ! 16660: # THIS LOOP SEARCHES FOR NEGATION AND SELECTION CODE SO ! 16661: # THAT THE OFFSETS COMPUTED WHILST CODE WAS IN CODE BLOCK ! 16662: # CAN BE TRANSFORMED TO REDUCED VALUES APPLICABLE IN AN ! 16663: # EXBLK. ! 16664: # ! 16665: exbl1: movl (r10)+,r9 # get next code word ! 16666: cmpl r9,$osla$ # jump if selection found ! 16667: beqlu exbl3 ! 16668: cmpl r9,$onta$ # jump if negation found ! 16669: beqlu exbl3 ! 16670: sobgtr r6,exbl1 # loop to end of code ! 16671: # ! 16672: # NO SELECTION FOUND OR MERGE TO EXIT ON TERMINATION ! 16673: # ! 16674: exbl2: movl (sp)+,r9 # pop exblk ptr into xr ! 16675: movl (sp)+,r10 # pop reduction constant ! 16676: rsb # return to caller ! 16677: #page ! 16678: # ! 16679: # EXBLD (CONTINUED) ! 16680: # ! 16681: # SELECTION OR NEGATION FOUND ! 16682: # REDUCE THE OFFSETS AS NEEDED. OFFSETS OCCUR IN WORDS ! 16683: # FOLLOWING CODE WORDS - ! 16684: # =ONTA$, =OSLA$, =OSLB$, =OSLC$ ! 16685: # ! 16686: exbl3: subl2 r7,(r10)+ # adjust offset ! 16687: sobgtr r6,exbl4 # decrement count ! 16688: # ! 16689: exbl4: sobgtr r6,exbl5 # decrement count ! 16690: # ! 16691: # CONTINUE SEARCH FOR MORE OFFSETS ! 16692: # ! 16693: exbl5: movl (r10)+,r9 # get next code word ! 16694: cmpl r9,$osla$ # jump if offset found ! 16695: beqlu exbl3 ! 16696: cmpl r9,$oslb$ # jump if offset found ! 16697: beqlu exbl3 ! 16698: cmpl r9,$oslc$ # jump if offset found ! 16699: beqlu exbl3 ! 16700: cmpl r9,$onta$ # jump if offset found ! 16701: beqlu exbl3 ! 16702: sobgtr r6,exbl5 # loop ! 16703: jmp exbl2 # merge to return ! 16704: #enp # end procedure exbld ! 16705: #page ! 16706: # ! 16707: # EXPAN -- ANALYZE EXPRESSION ! 16708: # ! 16709: # THE EXPRESSION ANALYZER (EXPAN) PROCEDURE IS USED TO SCAN ! 16710: # AN EXPRESSION AND CONVERT IT INTO A TREE REPRESENTATION. ! 16711: # SEE DESCRIPTIONS OF CMBLK, CUBLK, CBBLK IN THE STRUCTURES ! 16712: # SECTION FOR DETAILED FORMAT OF TREE BLOCKS. ! 16713: # ! 16714: # THE ANALYZER USES A SIMPLE PRECEDENCE SCHEME IN WHICH ! 16715: # OPERANDS AND OPERATORS ARE PLACED ON A SINGLE STACK ! 16716: # AND CONDENSATIONS ARE MADE WHEN LOW PRECEDENCE OPERATORS ! 16717: # ARE STACKED AFTER A HIGHER PRECEDENCE OPERATOR. A GLOBAL ! 16718: # VARIABLE (IN WB) KEEPS TRACK OF THE LEVEL AS FOLLOWS. ! 16719: # ! 16720: # 0 SCANNING OUTER LEVEL OF STATEMENT OR EXPRESSION ! 16721: # 1 SCANNING OUTER LEVEL OF NORMAL GOTO ! 16722: # 2 SCANNING OUTER LEVEL OF DIRECT GOTO ! 16723: # 3 SCANNING INSIDE ARRAY BRACKETS ! 16724: # 4 SCANNING INSIDE GROUPING PARENTHESES ! 16725: # 5 SCANNING INSIDE FUNCTION PARENTHESES ! 16726: # ! 16727: # THIS VARIABLE IS SAVED ON THE STACK ON ENCOUNTERING A ! 16728: # GROUPING AND RESTORED AT THE END OF THE GROUPING. ! 16729: # ! 16730: # ANOTHER GLOBAL VARIABLE (IN WC) COUNTS THE NUMBER OF ! 16731: # ITEMS AT ONE GROUPING LEVEL AND IS INCREMENTED FOR EACH ! 16732: # COMMA ENCOUNTERED. IT IS STACKED WITH THE LEVEL INDICATOR ! 16733: # ! 16734: # THE SCAN IS CONTROLLED BY A THREE STATE FINITE MACHINE. ! 16735: # A GLOBAL VARIABLE STORED IN WA IS THE CURRENT STATE. ! 16736: # ! 16737: # WA=0 NOTHING SCANNED AT THIS LEVEL ! 16738: # WA=1 OPERAND EXPECTED ! 16739: # WA=2 OPERATOR EXPECTED ! 16740: # ! 16741: # (WB) CALL TYPE (SEE BELOW) ! 16742: # JSR EXPAN CALL TO ANALYZE EXPRESSION ! 16743: # (XR) POINTER TO RESULTING TREE ! 16744: # (XL,WA,WB,WC,RA) DESTROYED ! 16745: # ! 16746: # THE ENTRY VALUE OF WB INDICATES THE CALL TYPE AS FOLLOWS. ! 16747: # ! 16748: # 0 SCANNING EITHER THE MAIN BODY OF A STATEMENT OR THE ! 16749: # TEXT OF AN EXPRESSION (FROM EVAL CALL). VALID ! 16750: # TERMINATORS ARE COLON, SEMICOLON. THE RESCAN FLAG IS ! 16751: # SET TO RETURN THE TERMINATOR ON THE NEXT SCANE CALL. ! 16752: # ! 16753: # 1 SCANNING A NORMAL GOTO. THE ONLY VALID ! 16754: # TERMINATOR IS A RIGHT PAREN. ! 16755: # ! 16756: # 2 SCANNING A DIRECT GOTO. THE ONLY VALID ! 16757: # TERMINATOR IS A RIGHT BRACKET. ! 16758: #page ! 16759: # ! 16760: # EXPAN (CONTINUED) ! 16761: # ! 16762: # ENTRY POINT ! 16763: # ! 16764: expan: #prc # entry point ! 16765: clrl -(sp) # set top of stack indicator ! 16766: clrl r6 # set initial state to zero ! 16767: clrl r8 # zero counter value ! 16768: # ! 16769: # LOOP HERE FOR SUCCESSIVE ENTRIES ! 16770: # ! 16771: exp01: jsb scane # scan next element ! 16772: addl2 r6,r10 # add state to syntax code ! 16773: casel r10,$0,$t$nes # switch on element type/state ! 16774: 5: ! 16775: .word exp27-5b # unop, s=0 ! 16776: .word exp27-5b # unop, s=1 ! 16777: .word exp04-5b # unop, s=2 ! 16778: .word exp06-5b # left paren, s=0 ! 16779: .word exp06-5b # left paren, s=1 ! 16780: .word exp04-5b # left paren, s=2 ! 16781: .word exp08-5b # left brkt, s=0 ! 16782: .word exp08-5b # left brkt, s=1 ! 16783: .word exp09-5b # left brkt, s=2 ! 16784: .word exp02-5b # comma, s=0 ! 16785: .word exp05-5b # comma, s=1 ! 16786: .word exp11-5b # comma, s=2 ! 16787: .word exp10-5b # function, s=0 ! 16788: .word exp10-5b # function, s=1 ! 16789: .word exp04-5b # function, s=2 ! 16790: .word exp03-5b # variable, s=0 ! 16791: .word exp03-5b # variable, state one ! 16792: .word exp04-5b # variable, s=2 ! 16793: .word exp03-5b # constant, s=0 ! 16794: .word exp03-5b # constant, s=1 ! 16795: .word exp04-5b # constant, s=2 ! 16796: .word exp05-5b # binop, s=0 ! 16797: .word exp05-5b # binop, s=1 ! 16798: .word exp26-5b # binop, s=2 ! 16799: .word exp02-5b # right paren, s=0 ! 16800: .word exp05-5b # right paren, s=1 ! 16801: .word exp12-5b # right paren, s=2 ! 16802: .word exp02-5b # right brkt, s=0 ! 16803: .word exp05-5b # right brkt, s=1 ! 16804: .word exp18-5b # right brkt, s=2 ! 16805: .word exp02-5b # colon, s=0 ! 16806: .word exp05-5b # colon, s=1 ! 16807: .word exp19-5b # colon, s=2 ! 16808: .word exp02-5b # semicolon, s=0 ! 16809: .word exp05-5b # semicolon, s=1 ! 16810: .word exp19-5b # semicolon, s=2 ! 16811: #esw # end switch on element type/state ! 16812: #page ! 16813: # ! 16814: # EXPAN (CONTINUED) ! 16815: # ! 16816: # HERE FOR RBR,RPR,COL,SMC,CMA IN STATE 0 ! 16817: # ! 16818: # SET TO RESCAN THE TERMINATOR ENCOUNTERED AND CREATE ! 16819: # A NULL CONSTANT (CASE OF OMITTED NULL) ! 16820: # ! 16821: exp02: movl sp,scnrs # set to rescan element ! 16822: movl $nulls,r9 # point to null, merge ! 16823: # ! 16824: # HERE FOR VAR OR CON IN STATES 0,1 ! 16825: # ! 16826: # STACK THE VARIABLE/CONSTANT AND SET STATE=2 ! 16827: # ! 16828: exp03: movl r9,-(sp) # stack pointer to operand ! 16829: movl $num02,r6 # set state 2 ! 16830: jmp exp01 # jump for next element ! 16831: # ! 16832: # HERE FOR VAR,CON,LPR,FNC,UOP IN STATE 2 ! 16833: # ! 16834: # WE RESCAN THE ELEMENT AND CREATE A CONCATENATION OPERATOR ! 16835: # THIS IS THE CASE OF THE BLANK CONCATENATION OPERATOR. ! 16836: # ! 16837: exp04: movl sp,scnrs # set to rescan element ! 16838: movl $opdvc,r9 # point to concat operator dv ! 16839: tstl r7 # ok if at top level ! 16840: beqlu exp4a ! 16841: movl $opdvp,r9 # else point to unmistakable concat. ! 16842: # ! 16843: # MERGE HERE WHEN XR SET UP WITH PROPER CONCATENATION DVBLK ! 16844: # ! 16845: exp4a: tstl scnbl # merge bop if blanks, else error ! 16846: beqlu 0f ! 16847: jmp exp26 ! 16848: 0: ! 16849: decl scnse # adjust start of element location ! 16850: jmp er_220 # syntax error. missing operator ! 16851: # ! 16852: # HERE FOR CMA,RPR,RBR,COL,SMC,BOP(S=1) BOP(S=0) ! 16853: # ! 16854: # THIS IS AN ERRONOUS CONTRUCTION ! 16855: # ! 16856: exp05: decl scnse # adjust start of element location ! 16857: jmp er_221 # syntax error. missing operand ! 16858: # ! 16859: # HERE FOR LPR (S=0,1) ! 16860: # ! 16861: exp06: movl $num04,r10 # set new level indicator ! 16862: clrl r9 # set zero value for cmopn ! 16863: #page ! 16864: # ! 16865: # EXPAN (CONTINUED) ! 16866: # ! 16867: # MERGE HERE TO STORE OLD LEVEL ON STACK AND START NEW ONE ! 16868: # ! 16869: exp07: movl r9,-(sp) # stack cmopn value ! 16870: movl r8,-(sp) # stack old counter ! 16871: movl r7,-(sp) # stack old level indicator ! 16872: jsb sbchk # check for stack overflow ! 16873: clrl r6 # set new state to zero ! 16874: movl r10,r7 # set new level indicator ! 16875: movl $num01,r8 # initialize new counter ! 16876: jmp exp01 # jump to scan next element ! 16877: # ! 16878: # HERE FOR LBR (S=0,1) ! 16879: # ! 16880: # THIS IS AN ILLEGAL USE OF LEFT BRACKET ! 16881: # ! 16882: exp08: jmp er_222 # syntax error. invalid use of left bracket ! 16883: # ! 16884: # HERE FOR LBR (S=2) ! 16885: # ! 16886: # SET NEW LEVEL AND START TO SCAN SUBSCRIPTS ! 16887: # ! 16888: exp09: movl (sp)+,r9 # load array ptr for cmopn ! 16889: movl $num03,r10 # set new level indicator ! 16890: jmp exp07 # jump to stack old and start new ! 16891: # ! 16892: # HERE FOR FNC (S=0,1) ! 16893: # ! 16894: # STACK OLD LEVEL AND START TO SCAN ARGUMENTS ! 16895: # ! 16896: exp10: movl $num05,r10 # set new lev indic (xr=vrblk=cmopn) ! 16897: jmp exp07 # jump to stack old and start new ! 16898: # ! 16899: # HERE FOR CMA (S=2) ! 16900: # ! 16901: # INCREMENT ARGUMENT COUNT AND CONTINUE ! 16902: # ! 16903: exp11: incl r8 # increment counter ! 16904: jsb expdm # dump operators at this level ! 16905: clrl -(sp) # set new level for parameter ! 16906: clrl r6 # set new state ! 16907: cmpl r7,$num02 # loop back unless outer level ! 16908: blequ 0f ! 16909: jmp exp01 ! 16910: 0: ! 16911: jmp er_223 # syntax error. invalid use of comma ! 16912: #page ! 16913: # ! 16914: # EXPAN (CONTINUED) ! 16915: # ! 16916: # HERE FOR RPR (S=2) ! 16917: # ! 16918: # AT OUTER LEVEL IN A NORMAL GOTO THIS IS A TERMINATOR ! 16919: # OTHERWISE IT MUST TERMINATE A FUNCTION OR GROUPING ! 16920: # ! 16921: exp12: cmpl r7,$num01 # end of normal goto ! 16922: bnequ 0f ! 16923: jmp exp20 ! 16924: 0: ! 16925: cmpl r7,$num05 # end of function arguments ! 16926: beqlu exp13 ! 16927: cmpl r7,$num04 # end of grouping / selection ! 16928: beqlu exp14 ! 16929: jmp er_224 # syntax error. unbalanced right parenthesis ! 16930: # ! 16931: # HERE AT END OF FUNCTION ARGUMENTS ! 16932: # ! 16933: exp13: movl $c$fnc,r10 # set cmtyp value for function ! 16934: jmp exp15 # jump to build cmblk ! 16935: # ! 16936: # HERE FOR END OF GROUPING ! 16937: # ! 16938: exp14: cmpl r8,$num01 # jump if end of grouping ! 16939: beqlu exp17 ! 16940: movl $c$sel,r10 # else set cmtyp for selection ! 16941: # ! 16942: # MERGE HERE TO BUILD CMBLK FOR LEVEL JUST SCANNED AND ! 16943: # TO POP UP TO THE PREVIOUS SCAN LEVEL BEFORE CONTINUING. ! 16944: # ! 16945: exp15: jsb expdm # dump operators at this level ! 16946: movl r8,r6 # copy count ! 16947: addl2 $cmvls,r6 # add for standard fields at start ! 16948: moval 0[r6],r6 # convert length to bytes ! 16949: jsb alloc # allocate space for cmblk ! 16950: movl $b$cmt,(r9) # store type code for cmblk ! 16951: movl r10,4*cmtyp(r9) # store cmblk node type indicator ! 16952: movl r6,4*cmlen(r9) # store length ! 16953: addl2 r6,r9 # point past end of block ! 16954: # set loop counter ! 16955: # ! 16956: # LOOP TO MOVE REMAINING WORDS TO CMBLK ! 16957: # ! 16958: exp16: movl (sp)+,-(r9) # move one operand ptr from stack ! 16959: movl (sp)+,r7 # pop to old level indicator ! 16960: sobgtr r8,exp16 # loop till all moved ! 16961: #page ! 16962: # ! 16963: # EXPAN (CONTINUED) ! 16964: # ! 16965: # COMPLETE CMBLK AND STACK POINTER TO IT ON STACK ! 16966: # ! 16967: subl2 $4*cmvls,r9 # point back to start of block ! 16968: movl (sp)+,r8 # restore old counter ! 16969: movl (sp),4*cmopn(r9)# store operand ptr in cmblk ! 16970: movl r9,(sp) # stack cmblk pointer ! 16971: movl $num02,r6 # set new state ! 16972: jmp exp01 # back for next element ! 16973: # ! 16974: # HERE AT END OF A PARENTHESIZED EXPRESSION ! 16975: # ! 16976: exp17: jsb expdm # dump operators at this level ! 16977: movl (sp)+,r9 # restore xr ! 16978: movl (sp)+,r7 # restore outer level ! 16979: movl (sp)+,r8 # restore outer count ! 16980: movl r9,(sp) # store opnd over unused cmopn val ! 16981: movl $num02,r6 # set new state ! 16982: jmp exp01 # back for next ele8ent ! 16983: # ! 16984: # HERE FOR RBR (S=2) ! 16985: # ! 16986: # AT OUTER LEVEL IN A DIRECT GOTO, THIS IS A TERMINATOR. ! 16987: # OTHERWISE IT MUST TERMINATE A SUBSCRIPT LIST. ! 16988: # ! 16989: exp18: movl $c$arr,r10 # set cmtyp for array reference ! 16990: cmpl r7,$num03 # jump to build cmblk if end arrayref ! 16991: beqlu exp15 ! 16992: cmpl r7,$num02 # jump if end of direct goto ! 16993: bnequ 0f ! 16994: jmp exp20 ! 16995: 0: ! 16996: jmp er_225 # syntax error. unbalanced right bracket ! 16997: #page ! 16998: # ! 16999: # EXPAN (CONTINUED) ! 17000: # ! 17001: # HERE FOR COL,SMC (S=2) ! 17002: # ! 17003: # ERROR UNLESS TERMINATING STATEMENT BODY AT OUTER LEVEL ! 17004: # ! 17005: exp19: movl sp,scnrs # rescan terminator ! 17006: movl r7,r10 # copy level indicator ! 17007: casel r10,$0,$6 # switch on level indicator ! 17008: 5: ! 17009: .word exp20-5b # normal outer level ! 17010: .word exp22-5b # fail if normal goto ! 17011: .word exp23-5b # fail if direct goto ! 17012: .word exp24-5b # fail array brackets ! 17013: .word exp21-5b # fail if in grouping ! 17014: .word exp21-5b # fail function args ! 17015: #esw # end switch on level ! 17016: # ! 17017: # HERE AT NORMAL END OF EXPRESSION ! 17018: # ! 17019: exp20: jsb expdm # dump remaining operators ! 17020: movl (sp)+,r9 # load tree pointer ! 17021: addl2 $4,sp # pop off bottom of stack marker ! 17022: rsb # return to expan caller ! 17023: # ! 17024: # MISSING RIGHT PAREN ! 17025: # ! 17026: exp21: jmp er_226 # syntax error. missing right paren ! 17027: # ! 17028: # MISSING RIGHT PAREN IN GOTO FIELD ! 17029: # ! 17030: exp22: jmp er_227 # syntax error. right paren missing from goto ! 17031: # ! 17032: # MISSING BRACKET IN GOTO ! 17033: # ! 17034: exp23: jmp er_228 # syntax error. right bracket missing from goto ! 17035: # ! 17036: # MISSING ARRAY BRACKET ! 17037: # ! 17038: exp24: jmp er_229 # syntax error. missing right array bracket ! 17039: #page ! 17040: # ! 17041: # EXPAN (CONTINUED) ! 17042: # ! 17043: # LOOP HERE WHEN AN OPERATOR CAUSES AN OPERATOR DUMP ! 17044: # ! 17045: exp25: movl r9,expsv ! 17046: jsb expop # pop one operator ! 17047: movl expsv,r9 # restore op dv pointer and merge ! 17048: # ! 17049: # HERE FOR BOP (S=2) ! 17050: # ! 17051: # REMOVE OPERATORS (CONDENSE) FROM STACK UNTIL NO MORE ! 17052: # LEFT AT THIS LEVEL OR TOP ONE HAS LOWER PRECEDENCE. ! 17053: # LOOP HERE TILL THIS CONDITION IS MET. ! 17054: # ! 17055: exp26: movl 4*1(sp),r10 # load operator dvptr from stack ! 17056: cmpl r10,$num05 # jump if bottom of stack level ! 17057: blequ exp27 ! 17058: cmpl 4*dvrpr(r9),4*dvlpr(r10) # else pop if new prec is lo ! 17059: blssu exp25 ! 17060: # ! 17061: # HERE FOR UOP (S=0,1) ! 17062: # ! 17063: # BINARY OPERATOR MERGES AFTER PRECEDENCE CHECK ! 17064: # ! 17065: # THE OPERATOR DV IS STORED ON THE STACK AND THE SCAN ! 17066: # CONTINUES AFTER SETTING THE SCAN STATE TO ONE. ! 17067: # ! 17068: exp27: movl r9,-(sp) # stack operator dvptr on stack ! 17069: jsb sbchk # check for stack overflow ! 17070: movl $num01,r6 # set new state ! 17071: cmpl r9,$opdvs # back for next element unless = ! 17072: beqlu 0f ! 17073: jmp exp01 ! 17074: 0: ! 17075: # ! 17076: # HERE FOR SPECIAL CASE OF BINARY =. THE SYNTAX ALLOWS A ! 17077: # NULL RIGHT ARGUMENT FOR THIS OPERATOR TO BE LEFT ! 17078: # OUT. ACCORDINGLY WE RESET TO STATE ZERO TO GET PROPER ! 17079: # ACTION ON A TERMINATOR (SUPPLY A NULL CONSTANT). ! 17080: # ! 17081: clrl r6 # set state zero ! 17082: jmp exp01 # jump for next element ! 17083: #enp # end procedure expan ! 17084: #page ! 17085: # ! 17086: # EXPAP -- TEST FOR PATTERN MATCH TREE ! 17087: # ! 17088: # EXPAP IS PASSED AN EXPRESSION TREE TO DETERMINE IF IT ! 17089: # IS A PATTERN MATCH. THE FOLLOWING ARE RECOGIZED AS ! 17090: # MATCHES IN THE CONTEXT OF THIS CALL. ! 17091: # ! 17092: # 1) AN EXPLICIT USE OF BINARY QUESTION MARK ! 17093: # 2) A CONCATENATION ! 17094: # 3) AN ALTERNATION WHOSE LEFT OPERAND IS A CONCATENATION ! 17095: # ! 17096: # (XR) PTR TO EXPAN TREE ! 17097: # JSR EXPAP CALL TO TEST FOR PATTERN MATCH ! 17098: # PPM LOC TRANSFER LOC IF NOT A PATTERN MATCH ! 17099: # (WA) DESTROYED ! 17100: # (XR) UNCHANGED (IF NOT MATCH) ! 17101: # (XR) PTR TO BINARY OPERATOR BLK IF MATCH ! 17102: # ! 17103: expap: #prc # entry point ! 17104: movl r10,-(sp) # save xl ! 17105: cmpl (r9),$b$cmt # no match if not complex ! 17106: bnequ expp2 ! 17107: movl 4*cmtyp(r9),r6 # else load type code ! 17108: cmpl r6,$c$cnc # concatenation is a match ! 17109: beqlu expp1 ! 17110: cmpl r6,$c$pmt # binary question mark is a match ! 17111: beqlu expp1 ! 17112: cmpl r6,$c$alt # else not match unless alternation ! 17113: bnequ expp2 ! 17114: # ! 17115: # HERE FOR ALTERNATION. CHANGE (A B) / C TO A QM (B / C) ! 17116: # ! 17117: movl 4*cmlop(r9),r10 # load left operand pointer ! 17118: cmpl (r10),$b$cmt # not match if left opnd not complex ! 17119: bnequ expp2 ! 17120: cmpl 4*cmtyp(r10),$c$cnc # not match if left op not conc ! 17121: bnequ expp2 ! 17122: movl 4*cmrop(r10),4*cmlop(r9) # xr points to (b / c) ! 17123: movl r9,4*cmrop(r10) # set xl opnds to a, (b / c) ! 17124: movl r10,r9 # point to this altered node ! 17125: # ! 17126: # EXIT HERE FOR PATTERN MATCH ! 17127: # ! 17128: expp1: movl (sp)+,r10 # restore entry xl ! 17129: addl2 $4*1,(sp) # give pattern match return ! 17130: rsb ! 17131: # ! 17132: # EXIT HERE IF NOT PATTERN MATCH ! 17133: # ! 17134: expp2: movl (sp)+,r10 # restore entry xl ! 17135: movl (sp)+,r11 # give non-match return ! 17136: jmp *(r11)+ ! 17137: #enp # end procedure expap ! 17138: #page ! 17139: # ! 17140: # EXPDM -- DUMP OPERATORS AT CURRENT LEVEL (FOR EXPAN) ! 17141: # ! 17142: # EXPDM USES EXPOP TO CONDENSE ALL OPERATORS AT THIS SYNTAX ! 17143: # LEVEL. THE STACK BOTTOM IS RECOGNIZED FROM THE LEVEL ! 17144: # VALUE WHICH IS SAVED ON THE TOP OF THE STACK. ! 17145: # ! 17146: # JSR EXPDM CALL TO DUMP OPERATORS ! 17147: # (XS) POPPED AS REQUIRED ! 17148: # (XR,WA) DESTROYED ! 17149: # ! 17150: .data 1 ! 17151: expdm_s: .long 0 ! 17152: .text 0 ! 17153: expdm: movl (sp)+,expdm_s # entry point ! 17154: movl r10,r$exs # save xl value ! 17155: # ! 17156: # LOOP TO DUMP OPERATORS ! 17157: # ! 17158: exdm1: cmpl 4*1(sp),$num05 # jump if stack bottom (saved level ! 17159: blequ exdm2 ! 17160: jsb expop # else pop one operator ! 17161: jmp exdm1 # and loop back ! 17162: # ! 17163: # HERE AFTER POPPING ALL OPERATORS ! 17164: # ! 17165: exdm2: movl r$exs,r10 # restore xl ! 17166: clrl r$exs # release save location ! 17167: jmp *expdm_s # return to expdm caller ! 17168: #enp # end procedure expdm ! 17169: #page ! 17170: # ! 17171: # EXPOP-- POP OPERATOR (FOR EXPAN) ! 17172: # ! 17173: # EXPOP IS USED BY THE EXPAN ROUTINE TO CONDENSE ONE ! 17174: # OPERATOR FROM THE TOP OF THE SYNTAX STACK. AN APPROPRIATE ! 17175: # CMBLK IS BUILT FOR THE OPERATOR (UNARY OR BINARY) AND A ! 17176: # POINTER TO THIS CMBLK IS STACKED. ! 17177: # ! 17178: # EXPOP IS ALSO USED BY SCNGF (GOTO FIELD SCAN) PROCEDURE ! 17179: # ! 17180: # JSR EXPOP CALL TO POP OPERATOR ! 17181: # (XS) POPPED APPROPRIATELY ! 17182: # (XR,XL,WA) DESTROYED ! 17183: # ! 17184: .data 1 ! 17185: expop_s: .long 0 ! 17186: .text 0 ! 17187: expop: movl (sp)+,expop_s # entry point ! 17188: movl 4*1(sp),r9 # load operator dv pointer ! 17189: cmpl 4*dvlpr(r9),$lluno # jump if unary ! 17190: beqlu expo2 ! 17191: # ! 17192: # HERE FOR BINARY OPERATOR ! 17193: # ! 17194: movl $4*cmbs$,r6 # set size of binary operator cmblk ! 17195: jsb alloc # allocate space for cmblk ! 17196: movl (sp)+,4*cmrop(r9)# pop and store right operand ptr ! 17197: movl (sp)+,r10 # pop and load operator dv ptr ! 17198: movl (sp),4*cmlop(r9)# store left operand pointer ! 17199: # ! 17200: # COMMON EXIT POINT ! 17201: # ! 17202: expo1: movl $b$cmt,(r9) # store type code for cmblk ! 17203: movl 4*dvtyp(r10),4*cmtyp(r9) # store cmblk node type code ! 17204: movl r10,4*cmopn(r9) # store dvptr (=ptr to dac o$xxx) ! 17205: movl r6,4*cmlen(r9) # store cmblk length ! 17206: movl r9,(sp) # store resulting node ptr on stack ! 17207: jmp *expop_s # return to expop caller ! 17208: # ! 17209: # HERE FOR UNARY OPERATOR ! 17210: # ! 17211: expo2: movl $4*cmus$,r6 # set size of unary operator cmblk ! 17212: jsb alloc # allocate space for cmblk ! 17213: movl (sp)+,4*cmrop(r9)# pop and store operand pointer ! 17214: movl (sp),r10 # load operator dv pointer ! 17215: jmp expo1 # merge back to exit ! 17216: #enp # end procedure expop ! 17217: #page ! 17218: # ! 17219: # FLSTG -- FOLD STRING TO UPPER CASE ! 17220: # ! 17221: # FLSTG FOLDS A CHARACTER STRING CONTAINING LOWER CASE ! 17222: # CHARACCTERS TO ONE CONTAINING UPPER CASE CHARACTERS. ! 17223: # FOLDING IS ONLY DONE IF &CASE (KVCAS) IS NOT ZERO. ! 17224: # ! 17225: # (XR) STRING ARGUMENT ! 17226: # (WA) LENGTH OF STRING ! 17227: # JSR FLSTG CALL TO FOLD STRING ! 17228: # (XR) RESULT STRING (POSSIBLY ORIGINAL) ! 17229: # (WC) DESTROYED ! 17230: # ! 17231: flstg: #prc # entry point ! 17232: tstl kvcas # skip if &case is 0 ! 17233: beqlu fst99 ! 17234: movl r10,-(sp) # save xl across call ! 17235: movl r9,-(sp) # save original scblk ptr ! 17236: jsb alocs # allocate new string block ! 17237: movl (sp),r10 # point to original scblk ! 17238: movl r9,-(sp) # save pointer to new scblk ! 17239: movab cfp$f(r10),r10 # point to original chars ! 17240: movab cfp$f(r9),r9 # point to new chars ! 17241: clrl -(sp) # init did fold flag ! 17242: # load loop counter ! 17243: fst01: movzbl (r10)+,r6 # load character ! 17244: cmpl $ch$$a,r6 # skip if less than lc a ! 17245: bgtru fst02 ! 17246: cmpl r6,$ch$$$ # skip if greater than lc z ! 17247: bgtru fst02 ! 17248: bicl2 $ch$bl,r6 # fold character to upper case ! 17249: movl sp,(sp) # set did fold character flag ! 17250: fst02: movb r6,(r9)+ # store (possibly folded) character ! 17251: sobgtr r8,fst01 # loop thru entire string ! 17252: #csc r9 # complete store characters ! 17253: tstl (sp)+ # skip if folding done ! 17254: bnequ fst10 ! 17255: movl (sp)+,dnamp # do not need new scblk ! 17256: movl (sp)+,r9 # return original scblk ! 17257: jmp fst20 # merge below ! 17258: fst10: movl (sp)+,r9 # return new scblk ! 17259: addl2 $4,sp # throw away original scblk pointer ! 17260: fst20: movl 4*sclen(r9),r6 # reload string length ! 17261: movl (sp)+,r10 # restore xl ! 17262: fst99: rsb # return ! 17263: #enp ! 17264: #page ! 17265: # ! 17266: # GBCOL -- PERFORM GARBAGE COLLECTION ! 17267: # ! 17268: # GBCOL PERFORMS A GARBAGE COLLECTION ON THE DYNAMIC REGION ! 17269: # ALL BLOCKS WHICH ARE NO LONGER IN USE ARE ELIMINATED ! 17270: # BY MOVING BLOCKS WHICH ARE IN USE DOWN AND RESETTING ! 17271: # DNAMP, THE POINTER TO THE NEXT AVAILABLE LOCATION. ! 17272: # ! 17273: # (WB) MOVE OFFSET (SEE BELOW) ! 17274: # JSR GBCOL CALL TO COLLECT GARBAGE ! 17275: # (XR) DESTROYED ! 17276: # ! 17277: # THE FOLLOWING CONDITIONS MUST BE MET AT THE TIME WHEN ! 17278: # GBCOL IS CALLED. ! 17279: # ! 17280: # 1) ALL POINTERS TO BLOCKS IN THE DYNAMIC AREA MUST BE ! 17281: # ACCESSIBLE TO THE GARBAGE COLLECTOR. THIS MEANS ! 17282: # THAT THEY MUST OCCUR IN ONE OF THE FOLLOWING. ! 17283: # ! 17284: # A) MAIN STACK, WITH CURRENT TOP ! 17285: # ELEMENT BEING INDICATED BY XS ! 17286: # ! 17287: # B) IN RELOCATABLE FIELDS OF VRBLKS. ! 17288: # ! 17289: # C) IN REGISTER XL AT THE TIME OF CALL ! 17290: # ! 17291: # E) IN THE SPECIAL REGION OF WORKING ! 17292: # STORAGE WHERE NAMES BEGIN WITH R$. ! 17293: # ! 17294: # 2) ALL POINTERS MUST POINT TO THE START OF BLOCKS WITH ! 17295: # THE SOLE EXCEPTION OF THE CONTENTS OF THE CODE ! 17296: # POINTER REGISTER WHICH POINTS INTO THE R$COD BLOCK. ! 17297: # ! 17298: # 3) NO LOCATION WHICH APPEARS TO CONTAIN A POINTER ! 17299: # INTO THE DYNAMIC REGION MAY OCCUR UNLESS IT IS IN ! 17300: # FACT A POINTER TO THE START OF THE BLOCK. HOWEVER ! 17301: # POINTERS OUTSIDE THIS AREA MAY OCCUR AND WILL ! 17302: # NOT BE CHANGED BY THE GARBAGE COLLECTOR. ! 17303: # IT IS ESPECIALLY IMPORTANT TO MAKE SURE THAT XL ! 17304: # DOES NOT CONTAIN A GARBAGE VALUE FROM SOME PROCESS ! 17305: # CARRIED OUT BEFORE THE CALL TO THE COLLECTOR. ! 17306: # ! 17307: # GBCOL HAS THE CAPABILITY OF MOVING THE FINAL COMPACTED ! 17308: # RESULT UP IN MEMORY (WITH ADDRESSES ADJUSTED ACCORDINGLY) ! 17309: # THIS IS USED TO ADD SPACE TO THE STATIC REGION. THE ! 17310: # ENTRY VALUE OF WB IS THE NUMBER OF BYTES TO MOVE UP. ! 17311: # THE CALLER MUST GUARANTEE THAT THERE IS ENOUGH ROOM. ! 17312: # FURTHERMORE THE VALUE IN WB IF IT IS NON-ZERO, MUST BE AT ! 17313: # LEAST 256 SO THAT THE MWB INSTRUCTION CONDITIONS ARE MET. ! 17314: #page ! 17315: # ! 17316: # GBCOL (CONTINUED) ! 17317: # ! 17318: # THE ALGORITHM, WHICH IS A MODIFICATION OF THE LISP-2 ! 17319: # GARBAGE COLLECTOR DEVISED BY R.DEWAR AND K.BELCHER ! 17320: # TAKES THREE PASSES AS FOLLOWS. ! 17321: # ! 17322: # 1) ALL POINTERS IN MEMORY ARE SCANNED AND BLOCKS IN USE ! 17323: # DETERMINED FROM THIS SCAN. NOTE THAT THIS PROCEDURE ! 17324: # IS RECURSIVE AND USES THE MAIN STACK FOR LINKAGE. ! 17325: # THE MARKING PROCESS IS THUS SIMILAR TO THAT USED IN ! 17326: # A STANDARD LISP COLLECTOR. HOWEVER THE METHOD OF ! 17327: # ACTUALLY MARKING THE BLOCKS IS DIFFERENT. ! 17328: # ! 17329: # THE FIRST FIELD OF A BLOCK NORMALLY CONTAINS A ! 17330: # CODE ENTRY POINT POINTER. SUCH AN ENTRY POINTER ! 17331: # CAN BE DISTINGUISHED FROM THE ADDRESS OF ANY POINTER ! 17332: # TO BE PROCESSED BY THE COLLECTOR. DURING GARBAGE ! 17333: # COLLECTION, THIS WORD IS USED TO BUILD A BACK CHAIN ! 17334: # OF POINTERS THROUGH FIELDS WHICH POINT TO THE BLOCK. ! 17335: # THE END OF THE CHAIN IS MARKED BY THE OCCURENCE ! 17336: # OF THE WORD WHICH USED TO BE IN THE FIRST WORD OF ! 17337: # THE BLOCK. THIS BACKCHAIN SERVES BOTH AS A MARK ! 17338: # INDICATING THAT THE BLOCK IS IN USE AND AS A LIST OF ! 17339: # REFERENCES FOR THE RELOCATION PHASE. ! 17340: # ! 17341: # 2) STORAGE IS SCANNED SEQUENTIALLY TO DISCOVER WHICH ! 17342: # BLOCKS ARE CURRENTLY IN USE AS INDICATED BY THE ! 17343: # PRESENCE OF A BACKCHAIN. TWO POINTERS ARE MAINTAINED ! 17344: # ONE SCANS THROUGH LOOKING AT EACH BLOCK. THE OTHER ! 17345: # IS INCREMENTED ONLY FOR BLOCKS FOUND TO BE IN USE. ! 17346: # IN THIS WAY, THE EVENTUAL LOCATION OF EACH BLOCK CAN ! 17347: # BE DETERMINED WITHOUT ACTUALLY MOVING ANY BLOCKS. ! 17348: # AS EACH BLOCK WHICH IS IN USE IS PROCESSED, THE BACK ! 17349: # CHAIN IS USED TO RESET ALL POINTERS WHICH POINT TO ! 17350: # THIS BLOCK TO CONTAIN ITS NEW ADDRESS, I.E. THE ! 17351: # ADDRESS IT WILL OCCUPY AFTER THE BLOCKS ARE MOVED. ! 17352: # THE FIRST WORD OF THE BLOCK, TAKEN FROM THE END OF ! 17353: # THE CHAIN IS RESTORED AT THIS POINT. ! 17354: # ! 17355: # DURING PASS 2, THE COLLECTOR BUILDS BLOCKS WHICH ! 17356: # DESCRIBE THE REGIONS OF STORAGE WHICH ARE TO BE ! 17357: # MOVED IN THE THIRD PASS. THERE IS ONE DESCRIPTOR FOR ! 17358: # EACH CONTIGUOUS SET OF GOOD BLOCKS. THE DESCRIPTOR ! 17359: # IS BUILT JUST BEHIND THE BLOCK TO BE MOVED AND ! 17360: # CONTAINS A POINTER TO THE NEXT BLOCK AND THE NUMBER ! 17361: # OF WORDS TO BE MOVED. ! 17362: # ! 17363: # 3) IN THE THIRD AND FINAL PASS, THE MOVE DESCRIPTOR ! 17364: # BLOCKS BUILT IN PASS TWO ARE USED TO ACTUALLY MOVE ! 17365: # THE BLOCKS DOWN TO THE BOTTOM OF THE DYNAMIC REGION. ! 17366: # THE COLLECTION IS THEN COMPLETE AND THE NEXT ! 17367: # AVAILABLE LOCATION POINTER IS RESET. ! 17368: #page ! 17369: # ! 17370: # GBCOL (CONTINUED) ! 17371: # ! 17372: gbcol: #prc # entry point ! 17373: tstl dmvch # fail if in mid-dump ! 17374: beqlu 0f ! 17375: jmp gbc14 ! 17376: 0: ! 17377: movl sp,gbcfl # note gbcol entered ! 17378: movl r6,gbsva # save entry wa ! 17379: movl r7,gbsvb # save entry wb ! 17380: movl r8,gbsvc # save entry wc ! 17381: movl r10,-(sp) # save entry xl ! 17382: movl r3,r6 # get code pointer value ! 17383: subl2 r$cod,r6 # make relative ! 17384: movl r6,r3 # and restore ! 17385: # ! 17386: # PROCESS STACK ENTRIES ! 17387: # ! 17388: movl sp,r9 # point to stack front ! 17389: movl stbas,r10 # point past end of stack ! 17390: cmpl r10,r9 # ok if d-stack ! 17391: bgequ gbc00 ! 17392: movl r10,r9 # reverse if ... ! 17393: movl sp,r10 # ... u-stack ! 17394: # ! 17395: # PROCESS THE STACK ! 17396: # ! 17397: gbc00: jsb gbcpf # process pointers on stack ! 17398: # ! 17399: # PROCESS SPECIAL WORK LOCATIONS ! 17400: # ! 17401: movl $r$aaa,r9 # point to start of relocatable locs ! 17402: movl $r$yyy,r10 # point past end of relocatable locs ! 17403: jsb gbcpf # process work fields ! 17404: # ! 17405: # PREPARE TO PROCESS VARIABLE BLOCKS ! 17406: # ! 17407: movl hshtb,r6 # point to first hash slot pointer ! 17408: # ! 17409: # LOOP THROUGH HASH SLOTS ! 17410: # ! 17411: gbc01: movl r6,r10 # point to next slot ! 17412: addl2 $4,r6 # bump bucket pointer ! 17413: movl r6,gbcnm # save bucket pointer ! 17414: #page ! 17415: # ! 17416: # GBCOL (CONTINUED) ! 17417: # ! 17418: # LOOP THROUGH VARIABLES ON ONE HASH CHAIN ! 17419: # ! 17420: gbc02: movl (r10),r9 # load ptr to next vrblk ! 17421: tstl r9 # jump if end of chain ! 17422: beqlu gbc03 ! 17423: movl r9,r10 # else copy vrblk pointer ! 17424: addl2 $4*vrval,r9 # point to first reloc fld ! 17425: addl2 $4*vrnxt,r10 # point past last (and to link ptr) ! 17426: jsb gbcpf # process reloc fields in vrblk ! 17427: jmp gbc02 # loop back for next block ! 17428: # ! 17429: # HERE AT END OF ONE HASH CHAIN ! 17430: # ! 17431: gbc03: movl gbcnm,r6 # restore bucket pointer ! 17432: cmpl r6,hshte # loop back if more buckets to go ! 17433: bnequ gbc01 ! 17434: #page ! 17435: # ! 17436: # GBCOL (CONTINUED) ! 17437: # ! 17438: # NOW WE ARE READY TO START PASS TWO. REGISTERS ARE USED ! 17439: # AS FOLLOWS IN PASS TWO. ! 17440: # ! 17441: # (XR) SCANS THROUGH ALL BLOCKS ! 17442: # (WC) POINTER TO EVENTUAL LOCATION ! 17443: # ! 17444: # THE MOVE DESCRIPTION BLOCKS BUILT IN THIS PASS HAVE ! 17445: # THE FOLLOWING FORMAT. ! 17446: # ! 17447: # WORD 1 POINTER TO NEXT MOVE BLOCK, ! 17448: # ZERO IF END OF CHAIN OF BLOCKS ! 17449: # ! 17450: # WORD 2 LENGTH OF BLOCKS TO BE MOVED IN ! 17451: # BYTES. SET TO THE ADDRESS OF THE ! 17452: # FIRST BYTE WHILE ACTUALLY SCANNING ! 17453: # THE BLOCKS. ! 17454: # ! 17455: # THE FIRST ENTRY ON THIS CHAIN IS A SPECIAL ENTRY ! 17456: # CONSISTING OF THE TWO WORDS GBCNM AND GBCNS. AFTER ! 17457: # BUILDING THE CHAIN OF MOVE DESCRIPTORS, GBCNM POINTS TO ! 17458: # THE FIRST REAL MOVE BLOCK, AND GBCNS IS THE LENGTH OF ! 17459: # BLOCKS IN USE AT THE START OF STORAGE WHICH NEED NOT ! 17460: # BE MOVED SINCE THEY ARE IN THE CORRECT POSITION. ! 17461: # ! 17462: gbc04: movl dnamb,r9 # point to first block ! 17463: movl r9,r8 # set as first eventual location ! 17464: addl2 gbsvb,r8 # add offset for eventual move up ! 17465: clrl gbcnm # clear initial forward pointer ! 17466: movl $gbcnm,gbclm # initialize ptr to last move block ! 17467: movl r9,gbcns # initialize first address ! 17468: # ! 17469: # LOOP THROUGH A SERIES OF BLOCKS IN USE ! 17470: # ! 17471: gbc05: cmpl r9,dnamp # jump if end of used region ! 17472: beqlu gbc07 ! 17473: movl (r9),r6 # else get first word ! 17474: cmpl r6,$p$yyy # skip if not entry ptr (in use) ! 17475: bgequ gbc06 ! 17476: cmpl r6,$b$aaa # jump if entry pointer (unused) ! 17477: bgequ gbc07 ! 17478: # ! 17479: # HERE FOR BLOCK IN USE, LOOP TO RELOCATE REFERENCES ! 17480: # ! 17481: gbc06: movl r6,r10 # copy pointer ! 17482: movl (r10),r6 # load forward pointer ! 17483: movl r8,(r10) # relocate reference ! 17484: cmpl r6,$p$yyy # loop back if not end of chain ! 17485: bgequ gbc06 ! 17486: cmpl r6,$b$aaa # loop back if not end of chain ! 17487: blequ gbc06 ! 17488: #page ! 17489: # ! 17490: # GBCOL (CONTINUED) ! 17491: # ! 17492: # AT END OF CHAIN, RESTORE FIRST WORD AND BUMP PAST ! 17493: # ! 17494: movl r6,(r9) # restore first word ! 17495: jsb blkln # get length of this block ! 17496: addl2 r6,r9 # bump actual pointer ! 17497: addl2 r6,r8 # bump eventual pointer ! 17498: jmp gbc05 # loop back for next block ! 17499: # ! 17500: # HERE AT END OF A SERIES OF BLOCKS IN USE ! 17501: # ! 17502: gbc07: movl r9,r6 # copy pointer past last block ! 17503: movl gbclm,r10 # point to previous move block ! 17504: subl2 4*1(r10),r6 # subtract starting address ! 17505: movl r6,4*1(r10) # store length of block to be moved ! 17506: # ! 17507: # LOOP THROUGH A SERIES OF BLOCKS NOT IN USE ! 17508: # ! 17509: gbc08: cmpl r9,dnamp # jump if end of used region ! 17510: beqlu gbc10 ! 17511: movl (r9),r6 # else load first word of next block ! 17512: cmpl r6,$p$yyy # jump if in use ! 17513: bgequ gbc09 ! 17514: cmpl r6,$b$aaa # jump if in use ! 17515: blequ gbc09 ! 17516: jsb blkln # else get length of next block ! 17517: addl2 r6,r9 # push pointer ! 17518: jmp gbc08 # and loop back ! 17519: # ! 17520: # HERE FOR A BLOCK IN USE AFTER PROCESSING A SERIES OF ! 17521: # BLOCKS WHICH WERE NOT IN USE, BUILD NEW MOVE BLOCK. ! 17522: # ! 17523: gbc09: subl2 $4*num02,r9 # point 2 words behind for move block ! 17524: movl gbclm,r10 # point to previous move block ! 17525: movl r9,(r10) # set forward ptr in previous block ! 17526: clrl (r9) # zero forward ptr of new block ! 17527: movl r9,gbclm # remember address of this block ! 17528: movl r9,r10 # copy ptr to move block ! 17529: addl2 $4*num02,r9 # point back to block in use ! 17530: movl r9,4*1(r10) # store starting address ! 17531: jmp gbc06 # jump to process block in use ! 17532: #page ! 17533: # ! 17534: # GBCOL (CONTINUED) ! 17535: # ! 17536: # HERE FOR PASS THREE -- ACTUALLY MOVE THE BLOCKS DOWN ! 17537: # ! 17538: # (XL) POINTER TO OLD LOCATION ! 17539: # (XR) POINTER TO NEW LOCATION ! 17540: # ! 17541: gbc10: movl dnamb,r9 # point to start of storage ! 17542: addl2 gbcns,r9 # bump past unmoved blocks at start ! 17543: # ! 17544: # LOOP THROUGH MOVE DESCRIPTORS ! 17545: # ! 17546: gbc11: movl gbcnm,r10 # point to next move block ! 17547: tstl r10 # jump if end of chain ! 17548: beqlu gbc12 ! 17549: movl (r10)+,gbcnm # move pointer down chain ! 17550: movl (r10)+,r6 # get length to move ! 17551: jsb sbmvw # perform move ! 17552: jmp gbc11 # loop back ! 17553: # ! 17554: # NOW TEST FOR MOVE UP ! 17555: # ! 17556: gbc12: movl r9,dnamp # set next available loc ptr ! 17557: movl gbsvb,r7 # reload move offset ! 17558: tstl r7 # jump if no move required ! 17559: beqlu gbc13 ! 17560: movl r9,r10 # else copy old top of core ! 17561: addl2 r7,r9 # point to new top of core ! 17562: movl r9,dnamp # save new top of core pointer ! 17563: movl r10,r6 # copy old top ! 17564: subl2 dnamb,r6 # minus old bottom = length ! 17565: addl2 r7,dnamb # bump bottom to get new value ! 17566: jsb sbmwb # perform move (backwards) ! 17567: # ! 17568: # MERGE HERE TO EXIT ! 17569: # ! 17570: gbc13: movl gbsva,r6 # restore wa ! 17571: movl r3,r8 # get code pointer ! 17572: addl2 r$cod,r8 # make absolute again ! 17573: movl r8,r3 # and replace absolute value ! 17574: movl gbsvc,r8 # restore wc ! 17575: movl (sp)+,r10 # restore entry xl ! 17576: incl gbcnt # increment count of collections ! 17577: clrl r9 # clear garbage value in xr ! 17578: clrl gbcfl # note exit from gbcol ! 17579: rsb # exit to gbcol caller ! 17580: # ! 17581: # GARBAGE COLLECTION NOT ALLOWED WHILST DUMPING ! 17582: # ! 17583: gbc14: incl errft # fatal error ! 17584: jmp er_250 # insufficient memory to complete dump ! 17585: #enp # end procedure gbcol ! 17586: #page ! 17587: # ! 17588: # GBCPF -- PROCESS FIELDS FOR GARBAGE COLLECTOR ! 17589: # ! 17590: # THIS PROCEDURE IS USED BY THE GARBAGE COLLECTOR TO ! 17591: # PROCESS FIELDS IN PASS ONE. SEE GBCOL FOR FULL DETAILS. ! 17592: # ! 17593: # (XR) PTR TO FIRST LOCATION TO PROCESS ! 17594: # (XL) PTR PAST LAST LOCATION TO PROCESS ! 17595: # JSR GBCPF CALL TO PROCESS FIELDS ! 17596: # (XR,WA,WB,WC,IA) DESTROYED ! 17597: # ! 17598: # NOTE THAT ALTHOUGH THIS PROCEDURE USES A RECURSIVE ! 17599: # APPROACH, IT CONTROLS ITS OWN STACK AND IS NOT RECURSIVE. ! 17600: # ! 17601: gbcpf: #prc # entry point ! 17602: clrl -(sp) # set zero to mark bottom of stack ! 17603: movl r10,-(sp) # save end pointer ! 17604: # ! 17605: # MERGE HERE TO GO DOWN A LEVEL AND START A NEW LOOP ! 17606: # ! 17607: # 1(XS) NEXT LVL FIELD PTR (0 AT OUTER LVL) ! 17608: # 0(XS) PTR PAST LAST FIELD TO PROCESS ! 17609: # (XR) PTR TO FIRST FIELD TO PROCESS ! 17610: # ! 17611: # LOOP TO PROCESS SUCCESSIVE FIELDS ! 17612: # ! 17613: gpf01: movl (r9),r10 # load field contents ! 17614: movl r9,r8 # save field pointer ! 17615: cmpl r10,dnamb # jump if not ptr into dynamic area ! 17616: blssu gpf02 ! 17617: cmpl r10,dnamp # jump if not ptr into dynamic area ! 17618: bgequ gpf02 ! 17619: # ! 17620: # HERE WE HAVE A PTR TO A BLOCK IN THE DYNAMIC AREA. ! 17621: # LINK THIS FIELD ONTO THE REFERENCE BACKCHAIN. ! 17622: # ! 17623: movl (r10),r6 # load ptr to chain (or entry ptr) ! 17624: movl r9,(r10) # set this field as new head of chain ! 17625: movl r6,(r9) # set forward pointer ! 17626: # ! 17627: # NOW SEE IF THIS BLOCK HAS BEEN PROCESSED BEFORE ! 17628: # ! 17629: cmpl r6,$p$yyy # jump if already processed ! 17630: bgequ gpf02 ! 17631: cmpl r6,$b$aaa # jump if not already processed ! 17632: bgequ gpf03 ! 17633: # ! 17634: # HERE TO MOVE TO NEXT FIELD ! 17635: # ! 17636: gpf02: movl r8,r9 # restore field pointer ! 17637: addl2 $4,r9 # bump to next field ! 17638: cmpl r9,(sp) # loop back if more to go ! 17639: bnequ gpf01 ! 17640: #page ! 17641: # ! 17642: # GBCPF (CONTINUED) ! 17643: # ! 17644: # HERE WE POP UP A LEVEL AFTER FINISHING A BLOCK ! 17645: # ! 17646: movl (sp)+,r10 # restore pointer past end ! 17647: movl (sp)+,r8 # restore block pointer ! 17648: tstl r8 # continue loop unless outer levl ! 17649: bnequ gpf02 ! 17650: rsb # return to caller if outer level ! 17651: # ! 17652: # HERE TO PROCESS AN ACTIVE BLOCK WHICH HAS NOT BEEN DONE ! 17653: # ! 17654: gpf03: movl r10,r9 # copy block pointer ! 17655: movl r6,r10 # copy first word of block ! 17656: movzwl -2(r10),r10 # load entry point id (bl$xx) ! 17657: # ! 17658: # BLOCK TYPE SWITCH. NOTE THAT BLOCKS WITH NO RELOCATABLE ! 17659: # FIELDS JUST RETURN TO GPF02 HERE TO CONTINE TO NEXT FLD. ! 17660: # ! 17661: casel r10,$0,$bl$$$ # switch on block type ! 17662: 5: ! 17663: .word gpf06-5b # arblk ! 17664: .word gpf18-5b # bcblk ! 17665: .word gpf08-5b # cdblk ! 17666: .word gpf17-5b # exblk ! 17667: .word gpf02-5b # icblk ! 17668: .word gpf10-5b # nmblk ! 17669: .word gpf10-5b # p0blk ! 17670: .word gpf12-5b # p1blk ! 17671: .word gpf12-5b # p2blk ! 17672: .word gpf02-5b # rcblk ! 17673: .word gpf02-5b # scblk ! 17674: .word gpf02-5b # seblk ! 17675: .word gpf08-5b # tbblk ! 17676: .word gpf08-5b # vcblk ! 17677: .word gpf02-5b # xnblk ! 17678: .word gpf09-5b # xrblk ! 17679: .word gpf13-5b # pdblk ! 17680: .word gpf16-5b # trblk ! 17681: .word gpf02-5b # bfblk ! 17682: .word gpf07-5b # ccblk ! 17683: .word gpf04-5b # cmblk ! 17684: .word gpf02-5b # ctblk ! 17685: .word gpf02-5b # dfblk ! 17686: .word gpf02-5b # efblk ! 17687: .word gpf10-5b # evblk ! 17688: .word gpf11-5b # ffblk ! 17689: .word gpf02-5b # kvblk ! 17690: .word gpf14-5b # pfblk ! 17691: .word gpf15-5b # teblk ! 17692: #esw # end of jump table ! 17693: #page ! 17694: # ! 17695: # GBCPF (CONTINUED) ! 17696: # ! 17697: # CMBLK ! 17698: # ! 17699: gpf04: movl 4*cmlen(r9),r6 # load length ! 17700: movl $4*cmtyp,r7 # set offset ! 17701: # ! 17702: # HERE TO PUSH DOWN TO NEW LEVEL ! 17703: # ! 17704: # (WC) FIELD PTR AT PREVIOUS LEVEL ! 17705: # (XR) PTR TO NEW BLOCK ! 17706: # (WA) LENGTH (RELOC FLDS + FLDS AT START) ! 17707: # (WB) OFFSET TO FIRST RELOC FIELD ! 17708: # ! 17709: gpf05: addl2 r9,r6 # point past last reloc field ! 17710: addl2 r7,r9 # point to first reloc field ! 17711: movl r8,-(sp) # stack old field pointer ! 17712: movl r6,-(sp) # stack new limit pointer ! 17713: jsb sbchk # check for stack overflow ! 17714: jmp gpf01 # if ok, back to process ! 17715: # ! 17716: # ARBLK ! 17717: # ! 17718: gpf06: movl 4*arlen(r9),r6 # load length ! 17719: movl 4*arofs(r9),r7 # set offset to 1st reloc fld (arpro) ! 17720: jmp gpf05 # all set ! 17721: # ! 17722: # CCBLK ! 17723: # ! 17724: gpf07: movl 4*ccuse(r9),r6 # set length in use ! 17725: movl $4*ccuse,r7 # 1st word (make sure at least one) ! 17726: jmp gpf05 # all set ! 17727: #page ! 17728: # ! 17729: # GBCPF (CONTINUED) ! 17730: # ! 17731: # CDBLK, TBBLK, VCBLK ! 17732: # ! 17733: gpf08: movl 4*offs2(r9),r6 # load length ! 17734: movl $4*offs3,r7 # set offset ! 17735: jmp gpf05 # jump back ! 17736: # ! 17737: # XRBLK ! 17738: # ! 17739: gpf09: movl 4*xrlen(r9),r6 # load length ! 17740: movl $4*xrptr,r7 # set offset ! 17741: jmp gpf05 # jump back ! 17742: # ! 17743: # EVBLK, NMBLK, P0BLK ! 17744: # ! 17745: gpf10: movl $4*offs2,r6 # point past second field ! 17746: movl $4*offs1,r7 # offset is one (only reloc fld is 2) ! 17747: jmp gpf05 # all set ! 17748: # ! 17749: # FFBLK ! 17750: # ! 17751: gpf11: movl $4*ffofs,r6 # set length ! 17752: movl $4*ffnxt,r7 # set offset ! 17753: jmp gpf05 # all set ! 17754: # ! 17755: # P1BLK, P2BLK ! 17756: # ! 17757: gpf12: movl $4*parm2,r6 # length (parm2 is non-relocatable) ! 17758: movl $4*pthen,r7 # set offset ! 17759: jmp gpf05 # all set ! 17760: #page ! 17761: # ! 17762: # GBCPF (CONTINUED) ! 17763: # ! 17764: # PDBLK ! 17765: # ! 17766: gpf13: movl 4*pddfp(r9),r10 # load ptr to dfblk ! 17767: movl 4*dfpdl(r10),r6 # get pdblk length ! 17768: movl $4*pdfld,r7 # set offset ! 17769: jmp gpf05 # all set ! 17770: # ! 17771: # PFBLK ! 17772: # ! 17773: gpf14: movl $4*pfarg,r6 # length past last reloc ! 17774: movl $4*pfcod,r7 # offset to first reloc ! 17775: jmp gpf05 # all set ! 17776: # ! 17777: # TEBLK ! 17778: # ! 17779: gpf15: movl $4*tesi$,r6 # set length ! 17780: movl $4*tesub,r7 # and offset ! 17781: jmp gpf05 # all set ! 17782: # ! 17783: # TRBLK ! 17784: # ! 17785: gpf16: movl $4*trsi$,r6 # set length ! 17786: movl $4*trval,r7 # and offset ! 17787: jmp gpf05 # all set ! 17788: # ! 17789: # EXBLK ! 17790: # ! 17791: gpf17: movl 4*exlen(r9),r6 # load length ! 17792: movl $4*exflc,r7 # set offset ! 17793: jmp gpf05 # jump back ! 17794: # ! 17795: # BCBLK ! 17796: # ! 17797: gpf18: movl $4*bcsi$,r6 # set length ! 17798: movl $4*bcbuf,r7 # and offset ! 17799: jmp gpf05 # all set ! 17800: #enp # end procedure gbcpf ! 17801: #page ! 17802: # ! 17803: # GTARR -- GET ARRAY ! 17804: # ! 17805: # GTARR IS PASSED AN OBJECT AND RETURNS AN ARRAY IF POSSIBL ! 17806: # ! 17807: # (XR) VALUE TO BE CONVERTED ! 17808: # JSR GTARR CALL TO GET ARRAY ! 17809: # PPM LOC TRANSFER LOC FOR CONVERT IMPOSSIBLE ! 17810: # (XR) RESULTING ARRAY ! 17811: # (XL,WA,WB,WC) DESTROYED ! 17812: # ! 17813: gtarr: #prc # entry point ! 17814: movl (r9),r6 # load type word ! 17815: cmpl r6,$b$art # exit if already an array ! 17816: bnequ 0f ! 17817: jmp gtar8 ! 17818: 0: ! 17819: cmpl r6,$b$vct # exit if already an array ! 17820: bnequ 0f ! 17821: jmp gtar8 ! 17822: 0: ! 17823: cmpl r6,$b$tbt # else fail if not a table (sgd02) ! 17824: beqlu 0f ! 17825: jmp gta9a ! 17826: 0: ! 17827: # ! 17828: # HERE WE CONVERT A TABLE TO AN ARRAY ! 17829: # ! 17830: movl r9,-(sp) # replace tbblk pointer on stack ! 17831: clrl r9 # signal first pass ! 17832: clrl r7 # zero non-null element count ! 17833: # ! 17834: # THE FOLLOWING CODE IS EXECUTED TWICE. ON THE FIRST PASS, ! 17835: # SIGNALLED BY XR=0, THE NUMBER OF NON-NULL ELEMENTS IN ! 17836: # THE TABLE IS COUNTED IN WB. IN THE SECOND PASS, WHERE ! 17837: # XR IS A POINTER INTO THE ARBLK, THE NAME AND VALUE ARE ! 17838: # ENTERED INTO THE CURRENT ARBLK LOCATION. ! 17839: # ! 17840: gtar1: movl (sp),r10 # point to table ! 17841: addl2 4*tblen(r10),r10# point past last bucket ! 17842: subl2 $4*tbbuk,r10 # set first bucket offset ! 17843: movl r10,r6 # copy adjusted pointer ! 17844: # ! 17845: # LOOP THROUGH BUCKETS IN TABLE BLOCK ! 17846: # NEXT THREE LINES OF CODE RELY ON TENXT HAVING A VALUE ! 17847: # 1 LESS THAN TBBUK. ! 17848: # ! 17849: gtar2: movl r6,r10 # copy bucket pointer ! 17850: subl2 $4,r6 # decrement bucket pointer ! 17851: # ! 17852: # LOOP THROUGH TEBLKS ON ONE BUCKET CHAIN ! 17853: # ! 17854: gtar3: movl 4*tenxt(r10),r10# point to next teblk ! 17855: cmpl r10,(sp) # jump if chain end (tbblk ptr) ! 17856: beqlu gtar6 ! 17857: movl r10,cnvtp # else save teblk pointer ! 17858: # ! 17859: # LOOP TO FIND VALUE DOWN TRBLK CHAIN ! 17860: # ! 17861: gtar4: movl 4*teval(r10),r10# load value ! 17862: cmpl (r10),$b$trt # loop till value found ! 17863: beqlu gtar4 ! 17864: movl r10,r8 # copy value ! 17865: movl cnvtp,r10 # restore teblk pointer ! 17866: #page ! 17867: # ! 17868: # GTARR (CONTINUED) ! 17869: # ! 17870: # NOW CHECK FOR NULL AND TEST CASES ! 17871: # ! 17872: cmpl r8,$nulls # loop back to ignore null value ! 17873: beqlu gtar3 ! 17874: tstl r9 # jump if second pass ! 17875: bnequ gtar5 ! 17876: incl r7 # for the first pass, bump count ! 17877: jmp gtar3 # and loop back for next teblk ! 17878: # ! 17879: # HERE IN SECOND PASS ! 17880: # ! 17881: gtar5: movl 4*tesub(r10),(r9)+ # store subscript name ! 17882: movl r8,(r9)+ # store value in arblk ! 17883: jmp gtar3 # loop back for next teblk ! 17884: # ! 17885: # HERE AFTER SCANNING TEBLKS ON ONE CHAIN ! 17886: # ! 17887: gtar6: cmpl r6,(sp) # loop back if more buckets to go ! 17888: bnequ gtar2 ! 17889: tstl r9 # else jump if second pass ! 17890: bnequ gtar7 ! 17891: # ! 17892: # HERE AFTER COUNTING NON-NULL ELEMENTS ! 17893: # ! 17894: tstl r7 # fail if no non-null elements ! 17895: bnequ 0f ! 17896: jmp gtar9 ! 17897: 0: ! 17898: movl r7,r6 # else copy count ! 17899: addl2 r7,r6 # double (two words/element) ! 17900: addl2 $arvl2,r6 # add space for standard fields ! 17901: moval 0[r6],r6 # convert length to bytes ! 17902: cmpl r6,mxlen # fail if too long for array ! 17903: blssu 0f ! 17904: jmp gtar9 ! 17905: 0: ! 17906: jsb alloc # else allocate space for arblk ! 17907: movl $b$art,(r9) # store type word ! 17908: clrl 4*idval(r9) # zero id for the moment ! 17909: movl r6,4*arlen(r9) # store length ! 17910: movl $num02,4*arndm(r9) # set dimensions = 2 ! 17911: movl intv1,r5 # get integer one ! 17912: movl r5,4*arlbd(r9) # store as lbd 1 ! 17913: movl r5,4*arlb2(r9) # store as lbd 2 ! 17914: movl intv2,r5 # load integer two ! 17915: movl r5,4*ardm2(r9) # store as dim 2 ! 17916: movl r7,r5 # get element count as integer ! 17917: movl r5,4*ardim(r9) # store as dim 1 ! 17918: clrl 4*arpr2(r9) # zero prototype field for now ! 17919: movl $4*arpr2,4*arofs(r9) # set offset field (signal pass 2) ! 17920: movl r9,r7 # save arblk pointer ! 17921: addl2 $4*arvl2,r9 # point to first element location ! 17922: jmp gtar1 # jump back to fill in elements ! 17923: #page ! 17924: # ! 17925: # GTARR (CONTINUED) ! 17926: # ! 17927: # HERE AFTER FILLING IN ELEMENT VALUES ! 17928: # ! 17929: gtar7: movl r7,r9 # restore arblk pointer ! 17930: movl r7,(sp) # store as result ! 17931: # ! 17932: # NOW WE NEED THE ARRAY PROTOTYPE WHICH IS OF THE FORM NN,2 ! 17933: # THIS IS OBTAINED BY BUILDING THE STRING FOR NN02 AND ! 17934: # CHANGING THE ZERO TO A COMMA BEFORE STORING IT. ! 17935: # ! 17936: movl 4*ardim(r9),r5 # get number of elements (nn) ! 17937: mull2 intvh,r5 # multiply by 100 ! 17938: addl2 intv2,r5 # add 2 (nn02) ! 17939: jsb icbld # build integer ! 17940: movl r9,-(sp) # store ptr for gtstg ! 17941: jsb gtstg # convert to string ! 17942: .long invalid$ # convert fail is impossible ! 17943: movl r9,r10 # copy string pointer ! 17944: movl (sp)+,r9 # reload arblk pointer ! 17945: movl r10,4*arpr2(r9) # store prototype ptr (nn02) ! 17946: subl2 $num02,r6 # adjust length to point to zero ! 17947: movab cfp$f(r10)[r6],r10 # point to zero ! 17948: movl $ch$cm,r7 # load a comma ! 17949: movb r7,(r10) # store a comma over the zero ! 17950: #csc r10 # complete store characters ! 17951: # ! 17952: # NORMAL RETURN ! 17953: # ! 17954: gtar8: addl2 $4*1,(sp) # return to caller ! 17955: rsb ! 17956: # ! 17957: # NON-CONVERSION RETURN ! 17958: # ! 17959: gtar9: movl (sp)+,r9 # restore stack for conv err (sgd02) ! 17960: # ! 17961: # MERGE TO TAKE CONVERT ERROR WHEN STACK ADJUSTED OK ! 17962: # ! 17963: gta9a: movl (sp)+,r11 # return ! 17964: jmp *(r11)+ ! 17965: #enp # procedure gtarr ! 17966: #page ! 17967: # ! 17968: # GTCOD -- CONVERT TO CODE ! 17969: # ! 17970: # (XR) OBJECT TO BE CONVERTED ! 17971: # JSR GTCOD CALL TO CONVERT TO CODE ! 17972: # PPM LOC TRANSFER LOC IF CONVERT IMPOSSIBLE ! 17973: # (XR) POINTER TO RESULTING CDBLK ! 17974: # (XL,WA,WB,WC,RA) DESTROYED ! 17975: # ! 17976: # IF A SPITBOL ERROR OCCURS DURING COMPILATION OR PRE- ! 17977: # EVALUATION, CONTROL IS PASSED VIA ERROR SECTION TO EXFAL ! 17978: # WITHOUT RETURNING TO THIS ROUTINE. ! 17979: # ! 17980: gtcod: #prc # entry point ! 17981: cmpl (r9),$b$cds # jump if already code ! 17982: beqlu gtcd1 ! 17983: cmpl (r9),$b$cdc # jump if already code ! 17984: beqlu gtcd1 ! 17985: # ! 17986: # HERE WE MUST GENERATE A CDBLK BY COMPILATION ! 17987: # ! 17988: movl r9,-(sp) # stack argument for gtstg ! 17989: jsb gtstg # convert argument to string ! 17990: .long gtcd2 # jump if non-convertible ! 17991: movl flptr,gtcef # save fail ptr in case of error ! 17992: movl r$cod,r$gtc # also save code ptr ! 17993: movl r9,r$cim # else set image pointer ! 17994: movl r6,scnil # set image length ! 17995: clrl scnpt # set scan pointer ! 17996: movl $stgxc,stage # set stage for execute compile ! 17997: movl cmpsn,lstsn # in case listr called ! 17998: jsb cmpil # compile string ! 17999: movl $stgxt,stage # reset stage for execute time ! 18000: clrl r$cim # clear image ! 18001: # ! 18002: # MERGE HERE IF NO CONVERT REQUIRED ! 18003: # ! 18004: gtcd1: addl2 $4*1,(sp) # give normal gtcod return ! 18005: rsb ! 18006: # ! 18007: # HERE IF UNCONVERTIBLE ! 18008: # ! 18009: gtcd2: movl (sp)+,r11 # give error return ! 18010: jmp *(r11)+ ! 18011: #enp # end procedure gtcod ! 18012: #page ! 18013: # ! 18014: # GTEXP -- CONVERT TO EXPRESSION ! 18015: # ! 18016: # (XR) INPUT VALUE TO BE CONVERTED ! 18017: # JSR GTEXP CALL TO CONVERT TO EXPRESSION ! 18018: # PPM LOC TRANSFER LOC IF CONVERT IMPOSSIBLE ! 18019: # (XR) POINTER TO RESULT EXBLK OR SEBLK ! 18020: # (XL,WA,WB,WC,RA) DESTROYED ! 18021: # ! 18022: # IF A SPITBOL ERROR OCCURS DURING COMPILATION OR PRE- ! 18023: # EVALUATION, CONTROL IS PASSED VIA ERROR SECTION TO EXFAL ! 18024: # WITHOUT RETURNING TO THIS ROUTINE. ! 18025: # ! 18026: gtexp: #prc # entry point ! 18027: cmpl (r9),$b$e$$ # jump if already an expression ! 18028: bgtru 0f ! 18029: jmp gtex1 ! 18030: 0: ! 18031: movl r9,-(sp) # store argument for gtstg ! 18032: jsb gtstg # convert argument to string ! 18033: .long gtex2 # jump if unconvertible ! 18034: # ! 18035: # CHECK THE LAST CHARACTER OF THE STRING FOR COLON OR ! 18036: # SEMICOLON. THESE CHARACTERS CAN LEGITIMATELY END AN ! 18037: # EXPRESSION IN OPEN CODE, SO EXPAN WILL NOT DETECT THEM ! 18038: # AS ERRORS, BUT THEY ARE INVALID AS TERMINATORS FOR A ! 18039: # STRING THAT IS BEING CONVERTED TO EXPRESSION FORM. ! 18040: # ! 18041: movl r9,r10 # copy input string pointer (reg06) ! 18042: movab cfp$f(r10)[r6],r10 # point one past the string end (reg06) ! 18043: movzbl -(r10),r10 # fetch the last character (reg06) ! 18044: cmpl r10,$ch$cl # error if it is a semicolon (reg06) ! 18045: beqlu gtex2 ! 18046: cmpl r10,$ch$sm # or if it is a colon (reg06) ! 18047: beqlu gtex2 ! 18048: # ! 18049: # HERE WE CONVERT A STRING BY COMPILATION ! 18050: # ! 18051: movl r9,r$cim # set input image pointer ! 18052: clrl scnpt # set scan pointer ! 18053: movl r6,scnil # set input image length ! 18054: clrl r7 # set code for normal scan ! 18055: movl flptr,gtcef # save fail ptr in case of error ! 18056: movl r$cod,r$gtc # also save code ptr ! 18057: movl $stgev,stage # adjust stage for compile ! 18058: movl $t$uok,scntp # indicate unary operator acceptable ! 18059: jsb expan # build tree for expression ! 18060: clrl scnrs # reset rescan flag ! 18061: cmpl scnpt,scnil # error if not end of image ! 18062: bnequ gtex2 ! 18063: clrl r7 # set ok value for cdgex call ! 18064: movl r9,r10 # copy tree pointer ! 18065: jsb cdgex # build expression block ! 18066: clrl r$cim # clear pointer ! 18067: movl $stgxt,stage # restore stage for execute time ! 18068: # ! 18069: # MERGE HERE IF NO CONVERSION REQUIRED ! 18070: # ! 18071: gtex1: addl2 $4*1,(sp) # return to gtexp caller ! 18072: rsb ! 18073: # ! 18074: # HERE IF UNCONVERTIBLE ! 18075: # ! 18076: gtex2: movl (sp)+,r11 # take error exit ! 18077: jmp *(r11)+ ! 18078: #enp # end procedure gtexp ! 18079: #page ! 18080: # ! 18081: # GTINT -- GET INTEGER VALUE ! 18082: # ! 18083: # GTINT IS PASSED AN OBJECT AND RETURNS AN INTEGER AFTER ! 18084: # PERFORMING ANY NECESSARY CONVERSIONS. ! 18085: # ! 18086: # (XR) VALUE TO BE CONVERTED ! 18087: # JSR GTINT CALL TO CONVERT TO INTEGER ! 18088: # PPM LOC TRANSFER LOC FOR CONVERT IMPOSSIBLE ! 18089: # (XR) RESULTING INTEGER ! 18090: # (WC,RA) DESTROYED ! 18091: # (WA,WB) DESTROYED (ONLY ON CONVERSION ERR) ! 18092: # (XR) UNCHANGED (ON CONVERT ERROR) ! 18093: # ! 18094: gtint: #prc # entry point ! 18095: cmpl (r9),$b$icl # jump if already an integer ! 18096: beqlu gtin2 ! 18097: movl r6,gtina # else save wa ! 18098: movl r7,gtinb # save wb ! 18099: jsb gtnum # convert to numeric ! 18100: .long gtin3 # jump if unconvertible ! 18101: cmpl r6,$b$icl # jump if integer ! 18102: beqlu gtin1 ! 18103: # ! 18104: # HERE WE CONVERT A REAL TO INTEGER ! 18105: # ! 18106: movf 4*rcval(r9),r2 # load real value ! 18107: cvtfl r2,r5 # convert to integer (err if ovflow) ! 18108: bvs gtin3 ! 18109: jsb icbld # if ok build icblk ! 18110: # ! 18111: # HERE AFTER SUCCESSFUL CONVERSION TO INTEGER ! 18112: # ! 18113: gtin1: movl gtina,r6 # restore wa ! 18114: movl gtinb,r7 # restore wb ! 18115: # ! 18116: # COMMON EXIT POINT ! 18117: # ! 18118: gtin2: addl2 $4*1,(sp) # return to gtint caller ! 18119: rsb ! 18120: # ! 18121: # HERE ON CONVERSION ERROR ! 18122: # ! 18123: gtin3: movl (sp)+,r11 # take convert error exit ! 18124: jmp *(r11)+ ! 18125: #enp # end procedure gtint ! 18126: #page ! 18127: # ! 18128: # GTNUM -- GET NUMERIC VALUE ! 18129: # ! 18130: # GTNUM IS GIVEN AN OBJECT AND RETURNS EITHER AN INTEGER ! 18131: # OR A REAL, PERFORMING ANY NECESSARY CONVERSIONS. ! 18132: # ! 18133: # (XR) OBJECT TO BE CONVERTED ! 18134: # JSR GTNUM CALL TO CONVERT TO NUMERIC ! 18135: # PPM LOC TRANSFER LOC IF CONVERT IMPOSSIBLE ! 18136: # (XR) POINTER TO RESULT (INT OR REAL) ! 18137: # (WA) FIRST WORD OF RESULT BLOCK ! 18138: # (WB,WC,RA) DESTROYED ! 18139: # (XR) UNCHANGED (ON CONVERT ERROR) ! 18140: # ! 18141: gtnum: #prc # entry point ! 18142: movl (r9),r6 # load first word of block ! 18143: cmpl r6,$b$icl # jump if integer (no conversion) ! 18144: bnequ 0f ! 18145: jmp gtn34 ! 18146: 0: ! 18147: cmpl r6,$b$rcl # jump if real (no conversion) ! 18148: bnequ 0f ! 18149: jmp gtn34 ! 18150: 0: ! 18151: # ! 18152: # AT THIS POINT THE ONLY POSSIBILITY IS TO CONVERT A STRING ! 18153: # TO AN INTEGER OR REAL AS APPROPRIATE. ! 18154: # ! 18155: movl r9,-(sp) # stack argument in case convert err ! 18156: movl r9,-(sp) # stack argument for gtstg ! 18157: jsb gtstg # convert argument to string ! 18158: .long gtn36 # jump if unconvertible ! 18159: # ! 18160: # INITIALIZE NUMERIC CONVERSION ! 18161: # ! 18162: movl intv0,r5 # initialize integer result to zero ! 18163: tstl r6 # jump to exit with zero if null ! 18164: bnequ 0f ! 18165: jmp gtn32 ! 18166: 0: ! 18167: # set bct counter for following loops ! 18168: clrl gtnnf # tentatively indicate result + ! 18169: movl r5,gtnex # initialise exponent to zero ! 18170: clrl gtnsc # zero scale in case real ! 18171: clrl gtndf # reset flag for dec point found ! 18172: clrl gtnrd # reset flag for digits found ! 18173: movf reav0,r2 # zero real accum in case real ! 18174: movab cfp$f(r9),r9 # point to argument characters ! 18175: # ! 18176: # MERGE BACK HERE AFTER IGNORING LEADING BLANK ! 18177: # ! 18178: gtn01: movzbl (r9)+,r7 # load first character ! 18179: cmpl r7,$ch$d0 # jump if not digit ! 18180: blssu gtn02 ! 18181: cmpl r7,$ch$d9 # jump if first char is a digit ! 18182: blequ gtn06 ! 18183: #page ! 18184: # ! 18185: # GTNUM (CONTINUED) ! 18186: # ! 18187: # HERE IF FIRST DIGIT IS NON-DIGIT ! 18188: # ! 18189: gtn02: cmpl r7,$ch$bl # jump if non-blank ! 18190: bnequ gtn03 ! 18191: gtna2: sobgtr r6,gtn01 # else decr count and loop back ! 18192: jmp gtn07 # jump to return zero if all blanks ! 18193: # ! 18194: # HERE FOR FIRST CHARACTER NON-BLANK, NON-DIGIT ! 18195: # ! 18196: gtn03: cmpl r7,$ch$pl # jump if plus sign ! 18197: beqlu gtn04 ! 18198: cmpl r7,$ch$ht # horizontal tab equiv to blank ! 18199: beqlu gtna2 ! 18200: cmpl r7,$ch$mn # jump if not minus (may be real) ! 18201: beqlu 0f ! 18202: jmp gtn12 ! 18203: 0: ! 18204: movl sp,gtnnf # if minus sign, set negative flag ! 18205: # ! 18206: # MERGE HERE AFTER PROCESSING SIGN ! 18207: # ! 18208: gtn04: sobgtr r6,gtn05 # jump if chars left ! 18209: jmp gtn36 # else error ! 18210: # ! 18211: # LOOP TO FETCH CHARACTERS OF AN INTEGER ! 18212: # ! 18213: gtn05: movzbl (r9)+,r7 # load next character ! 18214: cmpl r7,$ch$d0 # jump if not a digit ! 18215: blssu gtn08 ! 18216: cmpl r7,$ch$d9 # jump if not a digit ! 18217: bgtru gtn08 ! 18218: # ! 18219: # MERGE HERE FOR FIRST DIGIT ! 18220: # ! 18221: gtn06: movl r5,gtnsi # save current value ! 18222: mull2 $10,r5 # current*10-(new dig) jump if ovflow ! 18223: bvc 0f ! 18224: jmp gtn35 ! 18225: 0: bicl2 $0xfffffff0,r7 ! 18226: subl2 r7,r5 ! 18227: bvc 1f ! 18228: jmp gtn35 ! 18229: 1: ! 18230: movl sp,gtnrd # set digit read flag ! 18231: sobgtr r6,gtn05 # else loop back if more chars ! 18232: # ! 18233: # HERE TO EXIT WITH CONVERTED INTEGER VALUE ! 18234: # ! 18235: gtn07: tstl gtnnf # jump if negative (all set) ! 18236: beqlu 0f ! 18237: jmp gtn32 ! 18238: 0: ! 18239: mnegl r5,r5 # else negate ! 18240: bvs 0f ! 18241: jmp gtn32 ! 18242: 0: ! 18243: jmp gtn36 # else signal error ! 18244: #page ! 18245: # ! 18246: # GTNUM (CONTINUED) ! 18247: # ! 18248: # HERE FOR A NON-DIGIT CHARACTER WHILE ATTEMPTING TO ! 18249: # CONVERT AN INTEGER, CHECK FOR TRAILING BLANKS OR REAL. ! 18250: # ! 18251: gtn08: cmpl r7,$ch$bl # jump if a blank ! 18252: beqlu gtna9 ! 18253: cmpl r7,$ch$ht # jump if horizontal tab ! 18254: beqlu gtna9 ! 18255: cvtlf r5,r2 # else convert integer to real ! 18256: mnegf r2,r2 # negate to get positive value ! 18257: jmp gtn12 # jump to try for real ! 18258: # ! 18259: # HERE WE SCAN OUT BLANKS TO END OF STRING ! 18260: # ! 18261: gtn09: movzbl (r9)+,r7 # get next char ! 18262: cmpl r7,$ch$ht # jump if horizontal tab ! 18263: beqlu gtna9 ! 18264: cmpl r7,$ch$bl # error if non-blank ! 18265: beqlu 0f ! 18266: jmp gtn36 ! 18267: 0: ! 18268: gtna9: sobgtr r6,gtn09 # loop back if more chars to check ! 18269: jmp gtn07 # return integer if all blanks ! 18270: # ! 18271: # LOOP TO COLLECT MANTISSA OF REAL ! 18272: # ! 18273: gtn10: movzbl (r9)+,r7 # load next character ! 18274: cmpl r7,$ch$d0 # jump if non-numeric ! 18275: bgequ 0f ! 18276: jmp gtn12 ! 18277: 0: ! 18278: cmpl r7,$ch$d9 # jump if non-numeric ! 18279: blequ 0f ! 18280: jmp gtn12 ! 18281: 0: ! 18282: # ! 18283: # MERGE HERE TO COLLECT FIRST REAL DIGIT ! 18284: # ! 18285: gtn11: subl2 $ch$d0,r7 # convert digit to number ! 18286: mulf2 reavt,r2 # multiply real by 10.0 ! 18287: bvc 0f ! 18288: jmp gtn36 ! 18289: 0: ! 18290: movf r2,gtnsr # save result ! 18291: movl r7,r5 # get new digit as integer ! 18292: cvtlf r5,r2 # convert new digit to real ! 18293: addf2 gtnsr,r2 # add to get new total ! 18294: addl2 gtndf,gtnsc # increment scale if after dec point ! 18295: movl sp,gtnrd # set digit found flag ! 18296: sobgtr r6,gtn10 # loop back if more chars ! 18297: jmp gtn22 # else jump to scale ! 18298: #page ! 18299: # ! 18300: # GTNUM (CONTINUED) ! 18301: # ! 18302: # HERE IF NON-DIGIT FOUND WHILE COLLECTING A REAL ! 18303: # ! 18304: gtn12: cmpl r7,$ch$dt # jump if not dec point ! 18305: bnequ gtn13 ! 18306: tstl gtndf # if dec point, error if one already ! 18307: beqlu 0f ! 18308: jmp gtn36 ! 18309: 0: ! 18310: movl $num01,gtndf # else set flag for dec point ! 18311: sobgtr r6,gtn10 # loop back if more chars ! 18312: jmp gtn22 # else jump to scale ! 18313: # ! 18314: # HERE IF NOT DECIMAL POINT ! 18315: # ! 18316: gtn13: cmpl r7,$ch$le # jump if e for exponent ! 18317: beqlu gtn15 ! 18318: cmpl r7,$ch$ld # jump if d for exponent ! 18319: beqlu gtn15 ! 18320: cmpl r7,$ch$$e # jump if e for exponent ! 18321: beqlu gtn15 ! 18322: cmpl r7,$ch$$d # jump if d for exponent ! 18323: beqlu gtn15 ! 18324: # ! 18325: # HERE CHECK FOR TRAILING BLANKS ! 18326: # ! 18327: gtn14: cmpl r7,$ch$bl # jump if blank ! 18328: beqlu gtnb4 ! 18329: cmpl r7,$ch$ht # jump if horizontal tab ! 18330: beqlu gtnb4 ! 18331: jmp gtn36 # error if non-blank ! 18332: # ! 18333: gtnb4: movzbl (r9)+,r7 # get next character ! 18334: sobgtr r6,gtn14 # loop back to check if more ! 18335: jmp gtn22 # else jump to scale ! 18336: # ! 18337: # HERE TO READ AND PROCESS AN EXPONENT ! 18338: # ! 18339: gtn15: clrl gtnes # set exponent sign positive ! 18340: movl intv0,r5 # initialize exponent to zero ! 18341: movl sp,gtndf # reset no dec point indication ! 18342: sobgtr r6,gtn16 # jump skipping past e or d ! 18343: jmp gtn36 # error if null exponent ! 18344: # ! 18345: # CHECK FOR EXPONENT SIGN ! 18346: # ! 18347: gtn16: movzbl (r9)+,r7 # load first exponent character ! 18348: cmpl r7,$ch$pl # jump if plus sign ! 18349: beqlu gtn17 ! 18350: cmpl r7,$ch$mn # else jump if not minus sign ! 18351: bnequ gtn19 ! 18352: movl sp,gtnes # set sign negative if minus sign ! 18353: # ! 18354: # MERGE HERE AFTER PROCESSING EXPONENT SIGN ! 18355: # ! 18356: gtn17: sobgtr r6,gtn18 # jump if chars left ! 18357: jmp gtn36 # else error ! 18358: # ! 18359: # LOOP TO CONVERT EXPONENT DIGITS ! 18360: # ! 18361: gtn18: movzbl (r9)+,r7 # load next character ! 18362: #page ! 18363: # ! 18364: # GTNUM (CONTINUED) ! 18365: # ! 18366: # MERGE HERE FOR FIRST EXPONENT DIGIT ! 18367: # ! 18368: gtn19: cmpl r7,$ch$d0 # jump if not digit ! 18369: blssu gtn20 ! 18370: cmpl r7,$ch$d9 # jump if not digit ! 18371: bgtru gtn20 ! 18372: mull2 $10,r5 # else current*10, subtract new digit ! 18373: bvc 0f ! 18374: jmp gtn36 ! 18375: 0: bicl2 $0xfffffff0,r7 ! 18376: subl2 r7,r5 ! 18377: bvc 1f ! 18378: jmp gtn36 ! 18379: 1: ! 18380: sobgtr r6,gtn18 # loop back if more chars ! 18381: jmp gtn21 # jump if exponent field is exhausted ! 18382: # ! 18383: # HERE TO CHECK FOR TRAILING BLANKS AFTER EXPONENT ! 18384: # ! 18385: gtn20: cmpl r7,$ch$bl # jump if blank ! 18386: beqlu gtnc0 ! 18387: cmpl r7,$ch$ht # jump if horizontal tab ! 18388: beqlu gtnc0 ! 18389: jmp gtn36 # error if non-blank ! 18390: # ! 18391: gtnc0: movzbl (r9)+,r7 # get next character ! 18392: sobgtr r6,gtn20 # loop back till all blanks scanned ! 18393: # ! 18394: # MERGE HERE AFTER COLLECTING EXPONENT ! 18395: # ! 18396: gtn21: movl r5,gtnex # save collected exponent ! 18397: tstl gtnes # jump if it was negative ! 18398: bnequ gtn22 ! 18399: mnegl r5,r5 # else complement ! 18400: bvc 0f ! 18401: jmp gtn36 ! 18402: 0: ! 18403: movl r5,gtnex # and store positive exponent ! 18404: # ! 18405: # MERGE HERE WITH EXPONENT (0 IF NONE GIVEN) ! 18406: # ! 18407: gtn22: tstl gtnrd # error if not digits collected ! 18408: bnequ 0f ! 18409: jmp gtn36 ! 18410: 0: ! 18411: tstl gtndf # error if no exponent or dec point ! 18412: bnequ 0f ! 18413: jmp gtn36 ! 18414: 0: ! 18415: movl gtnsc,r5 # else load scale as integer ! 18416: subl2 gtnex,r5 # subtract exponent ! 18417: bvc 0f ! 18418: jmp gtn36 ! 18419: 0: ! 18420: tstl r5 # jump if we must scale up ! 18421: blss gtn26 ! 18422: # ! 18423: # HERE WE HAVE A NEGATIVE EXPONENT, SO SCALE DOWN ! 18424: # ! 18425: movl r5,r6 # load scale factor, err if ovflow ! 18426: bgeq 0f ! 18427: jmp gtn36 ! 18428: 0: ! 18429: # ! 18430: # LOOP TO SCALE DOWN IN STEPS OF 10**10 ! 18431: # ! 18432: gtn23: cmpl r6,$num10 # jump if 10 or less to go ! 18433: blequ gtn24 ! 18434: divf2 reatt,r2 # else divide by 10**10 ! 18435: subl2 $num10,r6 # decrement scale ! 18436: jmp gtn23 # and loop back ! 18437: #page ! 18438: # ! 18439: # GTNUM (CONTINUED) ! 18440: # ! 18441: # HERE SCALE REST OF WAY FROM POWERS OF TEN TABLE ! 18442: # ! 18443: gtn24: tstl r6 # jump if scaled ! 18444: beqlu gtn30 ! 18445: movl $cfp$r,r7 # else get indexing factor ! 18446: movl $reav1,r9 # point to powers of ten table ! 18447: moval 0[r6],r6 # convert remaining scale to byte ofs ! 18448: # ! 18449: # LOOP TO POINT TO POWERS OF TEN TABLE ENTRY ! 18450: # ! 18451: gtn25: addl2 r6,r9 # bump pointer ! 18452: sobgtr r7,gtn25 # once for each value word ! 18453: divf2 (r9),r2 # scale down as required ! 18454: jmp gtn30 # and jump ! 18455: # ! 18456: # COME HERE TO SCALE RESULT UP (POSITIVE EXPONENT) ! 18457: # ! 18458: gtn26: mnegl r5,r5 # get absolute value of exponent ! 18459: bvc 0f ! 18460: jmp gtn36 ! 18461: 0: ! 18462: movl r5,r6 # acquire scale, error if ovflow ! 18463: bgeq 0f ! 18464: jmp gtn36 ! 18465: 0: ! 18466: # ! 18467: # LOOP TO SCALE UP IN STEPS OF 10**10 ! 18468: # ! 18469: gtn27: cmpl r6,$num10 # jump if 10 or less to go ! 18470: blequ gtn28 ! 18471: mulf2 reatt,r2 # else multiply by 10**10 ! 18472: bvc 0f ! 18473: jmp gtn36 ! 18474: 0: ! 18475: subl2 $num10,r6 # else decrement scale ! 18476: jmp gtn27 # and loop back ! 18477: # ! 18478: # HERE TO SCALE UP REST OF WAY WITH TABLE ! 18479: # ! 18480: gtn28: tstl r6 # jump if scaled ! 18481: beqlu gtn30 ! 18482: movl $cfp$r,r7 # else get indexing factor ! 18483: movl $reav1,r9 # point to powers of ten table ! 18484: moval 0[r6],r6 # convert remaining scale to byte ofs ! 18485: # ! 18486: # LOOP TO POINT TO PROPER ENTRY IN POWERS OF TEN TABLE ! 18487: # ! 18488: gtn29: addl2 r6,r9 # bump pointer ! 18489: sobgtr r7,gtn29 # once for each word in value ! 18490: mulf2 (r9),r2 # scale up ! 18491: bvc 0f ! 18492: jmp gtn36 ! 18493: 0: ! 18494: #page ! 18495: # ! 18496: # GTNUM (CONTINUED) ! 18497: # ! 18498: # HERE WITH REAL VALUE SCALED AND READY EXCEPT FOR SIGN ! 18499: # ! 18500: gtn30: tstl gtnnf # jump if positive ! 18501: beqlu gtn31 ! 18502: mnegf r2,r2 # else negate ! 18503: # ! 18504: # HERE WITH PROPERLY SIGNED REAL VALUE IN (RA) ! 18505: # ! 18506: gtn31: jsb rcbld # build real block ! 18507: jmp gtn33 # merge to exit ! 18508: # ! 18509: # HERE WITH PROPERLY SIGNED INTEGER VALUE IN (IA) ! 18510: # ! 18511: gtn32: jsb icbld # build icblk ! 18512: # ! 18513: # REAL MERGES HERE ! 18514: # ! 18515: gtn33: movl (r9),r6 # load first word of result block ! 18516: addl2 $4,sp # pop argument off stack ! 18517: # ! 18518: # COMMON EXIT POINT ! 18519: # ! 18520: gtn34: addl2 $4*1,(sp) # return to gtnum caller ! 18521: rsb ! 18522: # ! 18523: # COME HERE IF OVERFLOW OCCURS DURING COLLECTION OF INTEGER ! 18524: # ! 18525: gtn35: movl gtnsi,r5 # reload integer so far ! 18526: cvtlf r5,r2 # convert to real ! 18527: mnegf r2,r2 # make value positive ! 18528: jmp gtn11 # merge with real circuit ! 18529: # ! 18530: # HERE FOR UNCONVERTIBLE TO STRING OR CONVERSION ERROR ! 18531: # ! 18532: gtn36: movl (sp)+,r9 # reload original argument ! 18533: movl (sp)+,r11 # take convert-error exit ! 18534: jmp *(r11)+ ! 18535: #enp # end procedure gtnum ! 18536: #page ! 18537: # ! 18538: # GTNVR -- CONVERT TO NATURAL VARIABLE ! 18539: # ! 18540: # GTNVR LOCATES A VARIABLE BLOCK (VRBLK) GIVEN EITHER AN ! 18541: # APPROPRIATE NAME (NMBLK) OR A NON-NULL STRING (SCBLK). ! 18542: # ! 18543: # (XR) ARGUMENT ! 18544: # JSR GTNVR CALL TO CONVERT TO NATURAL VARIABLE ! 18545: # PPM LOC TRANSFER LOC IF CONVERT IMPOSSIBLE ! 18546: # (XR) POINTER TO VRBLK ! 18547: # (WA,WB) DESTROYED (CONVERSION ERROR ONLY) ! 18548: # (WC) DESTROYED ! 18549: # ! 18550: gtnvr: #prc # entry point ! 18551: cmpl (r9),$b$nml # jump if not name ! 18552: bnequ gnv02 ! 18553: movl 4*nmbas(r9),r9 # else load name base if name ! 18554: cmpl r9,state # skip if vrblk (in static region) ! 18555: bgtru 0f ! 18556: jmp gnv07 ! 18557: 0: ! 18558: # ! 18559: # COMMON ERROR EXIT ! 18560: # ! 18561: gnv01: movl (sp)+,r11 # take convert-error exit ! 18562: jmp *(r11)+ ! 18563: # ! 18564: # HERE IF NOT NAME ! 18565: # ! 18566: gnv02: movl r6,gnvsa # save wa ! 18567: movl r7,gnvsb # save wb ! 18568: movl r9,-(sp) # stack argument for gtstg ! 18569: jsb gtstg # convert argument to string ! 18570: .long gnv01 # jump if conversion error ! 18571: tstl r6 # null string is an error ! 18572: beqlu gnv01 ! 18573: jsb flstg # fold lower case to upper case ! 18574: movl r10,-(sp) # save xl ! 18575: movl r9,-(sp) # stack string ptr for later ! 18576: movl r9,r7 # copy string pointer ! 18577: addl2 $4*schar,r7 # point to characters of string ! 18578: movl r7,gnvst # save pointer to characters ! 18579: movl r6,r7 # copy length ! 18580: movab 3+(4*0)(r7),r7 # get number of words in name ! 18581: ashl $-2,r7,r7 ! 18582: movl r7,gnvnw # save for later ! 18583: jsb hashs # compute hash index for string ! 18584: ashq $-32,r4,r4 # compute hash offset by taking mod ! 18585: ediv hshnb,r4,r11,r5 ! 18586: movl r5,r8 # get as offset ! 18587: moval 0[r8],r8 # convert offset to bytes ! 18588: addl2 hshtb,r8 # point to proper hash chain ! 18589: subl2 $4*vrnxt,r8 # subtract offset to merge into loop ! 18590: #page ! 18591: # ! 18592: # GTNVR (CONTINUED) ! 18593: # ! 18594: # LOOP TO SEARCH HASH CHAIN ! 18595: # ! 18596: gnv03: movl r8,r10 # copy hash chain pointer ! 18597: movl 4*vrnxt(r10),r10# point to next vrblk on chain ! 18598: tstl r10 # jump if end of chain ! 18599: beqlu gnv08 ! 18600: movl r10,r8 # save pointer to this vrblk ! 18601: tstl 4*vrlen(r10) # jump if not system variable ! 18602: bnequ gnv04 ! 18603: movl 4*vrsvp(r10),r10# else point to svblk ! 18604: subl2 $4*vrsof,r10 # adjust offset for merge ! 18605: # ! 18606: # MERGE HERE WITH STRING PTR (LIKE VRBLK) IN XL ! 18607: # ! 18608: gnv04: cmpl r6,4*vrlen(r10) # back for next vrblk if lengths ne ! 18609: bnequ gnv03 ! 18610: addl2 $4*vrchs,r10 # else point to chars of chain entry ! 18611: movl gnvnw,r7 # get word counter to control loop ! 18612: movl gnvst,r9 # point to chars of new name ! 18613: # ! 18614: # LOOP TO COMPARE CHARACTERS OF THE TWO NAMES ! 18615: # ! 18616: gnv05: cmpl (r9),(r10) # jump if no match for next vrblk ! 18617: bnequ gnv03 ! 18618: addl2 $4,r9 # bump new name pointer ! 18619: addl2 $4,r10 # bump vrblk in chain name pointer ! 18620: sobgtr r7,gnv05 # else loop till all compared ! 18621: movl r8,r9 # we have found a match, get vrblk ! 18622: # ! 18623: # EXIT POINT AFTER FINDING VRBLK OR BUILDING NEW ONE ! 18624: # ! 18625: gnv06: movl gnvsa,r6 # restore wa ! 18626: movl gnvsb,r7 # restore wb ! 18627: addl2 $4,sp # pop string pointer ! 18628: movl (sp)+,r10 # restore xl ! 18629: # ! 18630: # COMMON EXIT POINT ! 18631: # ! 18632: gnv07: addl2 $4*1,(sp) # return to gtnvr caller ! 18633: rsb ! 18634: # ! 18635: # NOT FOUND, PREPARE TO SEARCH SYSTEM VARIABLE TABLE ! 18636: # ! 18637: gnv08: clrl r9 # clear garbage xr pointer ! 18638: movl r8,gnvhe # save ptr to end of hash chain ! 18639: cmpl r6,$num09 # cannot be system var if length gt 9 ! 18640: bgtru gnv14 ! 18641: movl r6,r10 # else copy length ! 18642: moval 0[r10],r10 # convert to byte offset ! 18643: movl l^vsrch(r10),r10# point to first svblk of this length ! 18644: #page ! 18645: # ! 18646: # GTNVR (CONTINUED) ! 18647: # ! 18648: # LOOP TO SEARCH ENTRIES IN STANDARD VARIABLE TABLE ! 18649: # ! 18650: gnv09: movl r10,gnvsp # save table pointer ! 18651: movl (r10)+,r8 # load svbit bit string ! 18652: movl (r10)+,r7 # load length from table entry ! 18653: cmpl r6,r7 # jump if end of right length entires ! 18654: bnequ gnv14 ! 18655: movl gnvnw,r7 # get word counter to control loop ! 18656: movl gnvst,r9 # point to chars of new name ! 18657: # ! 18658: # LOOP TO CHECK FOR MATCHING NAMES ! 18659: # ! 18660: gnv10: cmpl (r9),(r10) # jump if name mismatch ! 18661: bnequ gnv11 ! 18662: addl2 $4,r9 # else bump new name pointer ! 18663: addl2 $4,r10 # bump svblk pointer ! 18664: sobgtr r7,gnv10 # else loop until all checked ! 18665: # ! 18666: # HERE WE HAVE A MATCH IN THE STANDARD VARIABLE TABLE ! 18667: # ! 18668: clrl r8 # set vrlen value zero ! 18669: movl $4*vrsi$,r6 # set standard size ! 18670: jmp gnv15 # jump to build vrblk ! 18671: # ! 18672: # HERE IF NO MATCH WITH TABLE ENTRY IN SVBLKS TABLE ! 18673: # ! 18674: gnv11: addl2 $4,r10 # bump past word of chars ! 18675: sobgtr r7,gnv11 # loop back if more to go ! 18676: ashl $-svnbt,r8,r8 # remove uninteresting bits ! 18677: # ! 18678: # LOOP TO BUMP TABLE PTR FOR EACH FLAGGED WORD ! 18679: # ! 18680: gnv12: movl bits1,r7 # load bit to test ! 18681: mcoml r8,r11 # test for word present ! 18682: bicl2 r11,r7 ! 18683: tstl r7 # jump if not present ! 18684: beqlu gnv13 ! 18685: addl2 $4,r10 # else bump table pointer ! 18686: # ! 18687: # HERE AFTER DEALING WITH ONE WORD (ONE BIT) ! 18688: # ! 18689: gnv13: ashl $-1,r8,r8 # remove bit already processed ! 18690: tstl r8 # loop back if more bits to test ! 18691: bnequ gnv12 ! 18692: jmp gnv09 # else loop back for next svblk ! 18693: # ! 18694: # HERE IF NOT SYSTEM VARIABLE ! 18695: # ! 18696: gnv14: movl r6,r8 # copy vrlen value ! 18697: movl $vrchs,r6 # load standard size -chars ! 18698: addl2 gnvnw,r6 # adjust for chars of name ! 18699: moval 0[r6],r6 # convert length to bytes ! 18700: #page ! 18701: # ! 18702: # GTNVR (CONTINUED) ! 18703: # ! 18704: # MERGE HERE TO BUILD VRBLK ! 18705: # ! 18706: gnv15: jsb alost # allocate space for vrblk (static) ! 18707: movl r9,r7 # save vrblk pointer ! 18708: movl $stnvr,r10 # point to model variable block ! 18709: movl $4*vrlen,r6 # set length of standard fields ! 18710: jsb sbmvw # set initial fields of new block ! 18711: movl gnvhe,r10 # load pointer to end of hash chain ! 18712: movl r7,4*vrnxt(r10) # add new block to end of chain ! 18713: movl r8,(r9)+ # set vrlen field, bump ptr ! 18714: movl gnvnw,r6 # get length in words ! 18715: moval 0[r6],r6 # convert to length in bytes ! 18716: tstl r8 # jump if system variable ! 18717: beqlu gnv16 ! 18718: # ! 18719: # HERE FOR NON-SYSTEM VARIABLE -- SET CHARS OF NAME ! 18720: # ! 18721: movl (sp),r10 # point back to string name ! 18722: addl2 $4*schar,r10 # point to chars of name ! 18723: jsb sbmvw # move characters into place ! 18724: movl r7,r9 # restore vrblk pointer ! 18725: jmp gnv06 # jump back to exit ! 18726: # ! 18727: # HERE FOR SYSTEM VARIABLE CASE TO FILL IN FIELDS WHERE ! 18728: # NECESSARY FROM THE FIELDS PRESENT IN THE SVBLK. ! 18729: # ! 18730: gnv16: movl gnvsp,r10 # load pointer to svblk ! 18731: movl r10,(r9) # set svblk ptr in vrblk ! 18732: movl r7,r9 # restore vrblk pointer ! 18733: movl 4*svbit(r10),r7 # load bit indicators ! 18734: addl2 $4*svchs,r10 # point to characters of name ! 18735: addl2 r6,r10 # point past characters ! 18736: # ! 18737: # SKIP PAST KEYWORD NUMBER (SVKNM) IF PRESENT ! 18738: # ! 18739: movl btknm,r8 # load test bit ! 18740: mcoml r7,r11 # and to test ! 18741: bicl2 r11,r8 ! 18742: tstl r8 # jump if no keyword number ! 18743: beqlu gnv17 ! 18744: addl2 $4,r10 # else bump pointer ! 18745: #page ! 18746: # ! 18747: # GTNVR (CONTINUED) ! 18748: # ! 18749: # HERE TEST FOR FUNCTION (SVFNC AND SVNAR) ! 18750: # ! 18751: gnv17: movl btfnc,r8 # get test bit ! 18752: mcoml r7,r11 # and to test ! 18753: bicl2 r11,r8 ! 18754: tstl r8 # skip if no system function ! 18755: beqlu gnv18 ! 18756: movl r10,4*vrfnc(r9) # else point vrfnc to svfnc field ! 18757: addl2 $4*num02,r10 # and bump past svfnc, svnar fields ! 18758: # ! 18759: # NOW TEST FOR LABEL (SVLBL) ! 18760: # ! 18761: gnv18: movl btlbl,r8 # get test bit ! 18762: mcoml r7,r11 # and to test ! 18763: bicl2 r11,r8 ! 18764: tstl r8 # jump if bit is off (no system labl) ! 18765: beqlu gnv19 ! 18766: movl r10,4*vrlbl(r9) # else point vrlbl to svlbl field ! 18767: addl2 $4,r10 # bump past svlbl field ! 18768: # ! 18769: # NOW TEST FOR VALUE (SVVAL) ! 18770: # ! 18771: gnv19: movl btval,r8 # load test bit ! 18772: mcoml r7,r11 # and to test ! 18773: bicl2 r11,r8 ! 18774: tstl r8 # all done if no value ! 18775: bnequ 0f ! 18776: jmp gnv06 ! 18777: 0: ! 18778: movl (r10),4*vrval(r9)# else set initial value ! 18779: movl $b$vre,4*vrsto(r9) # set error store access ! 18780: jmp gnv06 # merge back to exit to caller ! 18781: #enp # end procedure gtnvr ! 18782: #page ! 18783: # ! 18784: # GTPAT -- GET PATTERN ! 18785: # ! 18786: # GTPAT IS PASSED AN OBJECT IN (XR) AND RETURNS A ! 18787: # PATTERN AFTER PERFORMING ANY NECESSARY CONVERSIONS ! 18788: # ! 18789: # (XR) INPUT ARGUMENT ! 18790: # JSR GTPAT CALL TO CONVERT TO PATTERN ! 18791: # PPM LOC TRANSFER LOC IF CONVERT IMPOSSIBLE ! 18792: # (XR) RESULTING PATTERN ! 18793: # (WA) DESTROYED ! 18794: # (WB) DESTROYED (ONLY ON CONVERT ERROR) ! 18795: # (XR) UNCHANGED (ONLY ON CONVERT ERROR) ! 18796: # ! 18797: gtpat: #prc # entry point ! 18798: cmpl (r9),$p$aaa # jump if pattern already ! 18799: bgequ gtpt5 ! 18800: # ! 18801: # HERE IF NOT PATTERN, TRY FOR STRING ! 18802: # ! 18803: movl r7,gtpsb # save wb ! 18804: movl r9,-(sp) # stack argument for gtstg ! 18805: jsb gtstg # convert argument to string ! 18806: .long gtpt2 # jump if impossible ! 18807: # ! 18808: # HERE WE HAVE A STRING ! 18809: # ! 18810: tstl r6 # jump if non-null ! 18811: bnequ gtpt1 ! 18812: # ! 18813: # HERE FOR NULL STRING. GENERATE POINTER TO NULL PATTERN. ! 18814: # ! 18815: movl $ndnth,r9 # point to nothen node ! 18816: jmp gtpt4 # jump to exit ! 18817: #page ! 18818: # ! 18819: # GTPAT (CONTINUED) ! 18820: # ! 18821: # HERE FOR NON-NULL STRING ! 18822: # ! 18823: gtpt1: movl $p$str,r7 # load pcode for multi-char string ! 18824: cmpl r6,$num01 # jump if multi-char string ! 18825: bnequ gtpt3 ! 18826: # ! 18827: # HERE FOR ONE CHARACTER STRING, SHARE ONE CHARACTER ANY ! 18828: # ! 18829: movab cfp$f(r9),r9 # point to character ! 18830: movzbl (r9),r6 # load character ! 18831: movl r6,r9 # set as parm1 ! 18832: movl $p$ans,r7 # point to pcode for 1-char any ! 18833: jmp gtpt3 # jump to build node ! 18834: # ! 18835: # HERE IF ARGUMENT IS NOT CONVERTIBLE TO STRING ! 18836: # ! 18837: gtpt2: movl $p$exa,r7 # set pcode for expression in case ! 18838: cmpl (r9),$b$e$$ # jump to build node if expression ! 18839: blequ gtpt3 ! 18840: # ! 18841: # HERE WE HAVE AN ERROR (CONVERSION IMPOSSIBLE) ! 18842: # ! 18843: movl (sp)+,r11 # take convert error exit ! 18844: jmp *(r11)+ ! 18845: # ! 18846: # MERGE HERE TO BUILD NODE FOR STRING OR EXPRESSION ! 18847: # ! 18848: gtpt3: jsb pbild # call routine to build pattern node ! 18849: # ! 18850: # COMMON EXIT AFTER SUCCESSFUL CONVERSION ! 18851: # ! 18852: gtpt4: movl gtpsb,r7 # restore wb ! 18853: # ! 18854: # MERGE HERE TO EXIT OF NO CONVERSION REQUIRED ! 18855: # ! 18856: gtpt5: addl2 $4*1,(sp) # return to gtpat caller ! 18857: rsb ! 18858: #enp # end procedure gtpat ! 18859: #page ! 18860: # ! 18861: # GTREA -- GET REAL VALUE ! 18862: # ! 18863: # GTREA IS PASSED AN OBJECT AND RETURNS A REAL VALUE ! 18864: # PERFORMING ANY NECESSARY CONVERSIONS. ! 18865: # ! 18866: # (XR) OBJECT TO BE CONVERTED ! 18867: # JSR GTREA CALL TO CONVERT OBJECT TO REAL ! 18868: # PPM LOC TRANSFER LOC IF CONVERT IMPOSSIBLE ! 18869: # (XR) POINTER TO RESULTING REAL ! 18870: # (WA,WB,WC,RA) DESTROYED ! 18871: # (XR) UNCHANGED (CONVERT ERROR ONLY) ! 18872: # ! 18873: gtrea: #prc # entry point ! 18874: movl (r9),r6 # get first word of block ! 18875: cmpl r6,$b$rcl # jump if real ! 18876: beqlu gtre2 ! 18877: jsb gtnum # else convert argument to numeric ! 18878: .long gtre3 # jump if unconvertible ! 18879: cmpl r6,$b$rcl # jump if real was returned ! 18880: beqlu gtre2 ! 18881: # ! 18882: # HERE FOR CASE OF AN INTEGER TO CONVERT TO REAL ! 18883: # ! 18884: gtre1: movl 4*icval(r9),r5 # load integer ! 18885: cvtlf r5,r2 # convert to real ! 18886: jsb rcbld # build rcblk ! 18887: # ! 18888: # EXIT WITH REAL ! 18889: # ! 18890: gtre2: addl2 $4*1,(sp) # return to gtrea caller ! 18891: rsb ! 18892: # ! 18893: # HERE ON CONVERSION ERROR ! 18894: # ! 18895: gtre3: movl (sp)+,r11 # take convert error exit ! 18896: jmp *(r11)+ ! 18897: #enp # end procedure gtrea ! 18898: #page ! 18899: # ! 18900: # GTSMI -- GET SMALL INTEGER ! 18901: # ! 18902: # GTSMI IS PASSED A SNOBOL OBJECT AND RETURNS AN ADDRESS ! 18903: # INTEGER IN THE RANGE (0 LE N LE DNAMB). SUCH A VALUE CAN ! 18904: # ONLY BE DERIVED FROM AN INTEGER IN THE APPROPRIATE RANGE. ! 18905: # SMALL INTEGERS NEVER APPEAR AS SNOBOL VALUES. HOWEVER, ! 18906: # THEY ARE USED INTERNALLY FOR A VARIETY OF PURPOSES. ! 18907: # ! 18908: # -(XS) ARGUMENT TO CONVERT (ON STACK) ! 18909: # JSR GTSMI CALL TO CONVERT TO SMALL INTEGER ! 18910: # PPM LOC TRANSFER LOC FOR NOT INTEGER ! 18911: # PPM LOC TRANSFER LOC FOR LT 0, GT DNAMB ! 18912: # (XR,WC) RESULTING SMALL INT (TWO COPIES) ! 18913: # (XS) POPPED ! 18914: # (RA) DESTROYED ! 18915: # (WA,WB) DESTROYED (ON CONVERT ERROR ONLY) ! 18916: # (XR) INPUT ARG (CONVERT ERROR ONLY) ! 18917: # ! 18918: .data 1 ! 18919: gtsmi_s: .long 0 ! 18920: .text 0 ! 18921: gtsmi: movl (sp)+,gtsmi_s # entry point ! 18922: movl (sp)+,r9 # load argument ! 18923: cmpl (r9),$b$icl # skip if already an integer ! 18924: beqlu gtsm1 ! 18925: # ! 18926: # HERE IF NOT AN INTEGER ! 18927: # ! 18928: jsb gtint # convert argument to integer ! 18929: .long gtsm2 # jump if convert is impossible ! 18930: # ! 18931: # MERGE HERE WITH INTEGER ! 18932: # ! 18933: gtsm1: movl 4*icval(r9),r5 # load integer value ! 18934: movl r5,r8 # move as one word, jump if ovflow ! 18935: bgeq 0f ! 18936: jmp gtsm3 ! 18937: 0: ! 18938: cmpl r8,mxlen # or if too small ! 18939: bgtru gtsm3 ! 18940: movl r8,r9 # copy result to xr ! 18941: addl3 $4*2,gtsmi_s,r11 # return to gtsmi caller ! 18942: jmp (r11) ! 18943: # ! 18944: # HERE IF UNCONVERTIBLE TO INTEGER ! 18945: # ! 18946: gtsm2: movl gtsmi_s,r11 # take non-integer error exit ! 18947: jmp *(r11)+ ! 18948: # ! 18949: # HERE IF OUT OF RANGE ! 18950: # ! 18951: gtsm3: addl3 $4*1,gtsmi_s,r11 # take out-of-range error exit ! 18952: jmp *(r11)+ ! 18953: #enp # end procedure gtsmi ! 18954: #page ! 18955: # ! 18956: # GTSTG -- GET STRING ! 18957: # ! 18958: # GTSTG IS PASSED AN OBJECT AND RETURNS A STRING WITH ! 18959: # ANY NECESSARY CONVERSIONS PERFORMED. ! 18960: # ! 18961: # -(XS) INPUT ARGUMENT (ON STACK) ! 18962: # JSR GTSTG CALL TO CONVERT TO STRING ! 18963: # PPM LOC TRANSFER LOC IF CONVERT IMPOSSIBLE ! 18964: # (XR) POINTER TO RESULTING STRING ! 18965: # (WA) LENGTH OF STRING IN CHARACTERS ! 18966: # (XS) POPPED ! 18967: # (RA) DESTROYED ! 18968: # (XR) INPUT ARG (CONVERT ERROR ONLY) ! 18969: # ! 18970: .data 1 ! 18971: gtstg_s: .long 0 ! 18972: .text 0 ! 18973: gtstg: movl (sp)+,gtstg_s # entry point ! 18974: movl (sp)+,r9 # load argument, pop stack ! 18975: cmpl (r9),$b$scl # jump if already a string ! 18976: bnequ 0f ! 18977: jmp gts30 ! 18978: 0: ! 18979: # ! 18980: # HERE IF NOT A STRING ALREADY ! 18981: # ! 18982: gts01: movl r9,-(sp) # restack argument in case error ! 18983: movl r10,-(sp) # save xl ! 18984: movl r7,gtsvb # save wb ! 18985: movl r8,gtsvc # save wc ! 18986: movl (r9),r6 # load first word of block ! 18987: cmpl r6,$b$icl # jump to convert integer ! 18988: beqlu gts05 ! 18989: cmpl r6,$b$rcl # jump to convert real ! 18990: bnequ 0f ! 18991: jmp gts10 ! 18992: 0: ! 18993: cmpl r6,$b$nml # jump to convert name ! 18994: beqlu gts03 ! 18995: cmpl r6,$b$bct # jump to convert buffer ! 18996: bnequ 0f ! 18997: jmp gts32 ! 18998: 0: ! 18999: # ! 19000: # HERE ON CONVERSION ERROR ! 19001: # ! 19002: gts02: movl (sp)+,r10 # restore xl ! 19003: movl (sp)+,r9 # reload input argument ! 19004: movl gtstg_s,r11 # take convert error exit ! 19005: jmp *(r11)+ ! 19006: #page ! 19007: # ! 19008: # GTSTG (CONTINUED) ! 19009: # ! 19010: # HERE TO CONVERT A NAME (ONLY POSSIBLE IF NATURAL VAR) ! 19011: # ! 19012: gts03: movl 4*nmbas(r9),r10 # load name base ! 19013: cmpl r10,state # error if not natural var (static) ! 19014: bgequ gts02 ! 19015: addl2 $4*vrsof,r10 # else point to possible string name ! 19016: movl 4*sclen(r10),r6 # load length ! 19017: tstl r6 # jump if not system variable ! 19018: bnequ gts04 ! 19019: movl 4*vrsvo(r10),r10# else point to svblk ! 19020: movl 4*svlen(r10),r6 # and load name length ! 19021: # ! 19022: # MERGE HERE WITH STRING IN XR, LENGTH IN WA ! 19023: # ! 19024: gts04: clrl r7 # set offset to zero ! 19025: jsb sbstr # use sbstr to copy string ! 19026: jmp gts29 # jump to exit ! 19027: # ! 19028: # COME HERE TO CONVERT AN INTEGER ! 19029: # ! 19030: gts05: movl 4*icval(r9),r5 # load integer value ! 19031: movl $num01,gtssf # set sign flag negative ! 19032: tstl r5 # skip if integer is negative ! 19033: blss gts06 ! 19034: mnegl r5,r5 # else negate integer ! 19035: clrl gtssf # and reset negative flag ! 19036: #page ! 19037: # ! 19038: # GTSTG (CONTINUED) ! 19039: # ! 19040: # HERE WITH SIGN FLAG SET AND SIGN FORCED NEGATIVE AS ! 19041: # REQUIRED BY THE CVD INSTRUCTION. ! 19042: # ! 19043: gts06: movl gtswk,r9 # point to result work area ! 19044: movl $nstmx,r7 # initialize counter to max length ! 19045: movab cfp$f(r9)[r7],r9# prepare to store (right-left) ! 19046: # ! 19047: # LOOP TO CONVERT DIGITS INTO WORK AREA ! 19048: # ! 19049: gts07: ashq $-32,r4,r4 # convert one digit into wa ! 19050: ediv $10,r4,r5,r6 ! 19051: mnegl r6,r6 ! 19052: bisb2 $0x30,r6 ! 19053: movb r6,-(r9) # store in work area ! 19054: decl r7 # decrement counter ! 19055: tstl r5 # loop if more digits to go ! 19056: bneq gts07 ! 19057: #csc r9 # complete store characters ! 19058: # ! 19059: # MERGE HERE AFTER CONVERTING INTEGER OR REAL INTO WORK ! 19060: # AREA. WB IS SET TO NSTMX - (NUMBER OF CHARS IN RESULT). ! 19061: # ! 19062: gts08: movl $nstmx,r6 # get max number of characters ! 19063: subl2 r7,r6 # compute length of result ! 19064: movl r6,r10 # remember length for move later on ! 19065: addl2 gtssf,r6 # add one for negative sign if needed ! 19066: jsb alocs # allocate string for result ! 19067: movl r9,r8 # save result pointer for the moment ! 19068: movab cfp$f(r9),r9 # point to chars of result block ! 19069: tstl gtssf # skip if positive ! 19070: beqlu gts09 ! 19071: movl $ch$mn,r6 # else load negative sign ! 19072: movb r6,(r9)+ # and store it ! 19073: #csc r9 # complete store characters ! 19074: # ! 19075: # HERE AFTER DEALING WITH SIGN ! 19076: # ! 19077: gts09: movl r10,r6 # recall length to move ! 19078: movl gtswk,r10 # point to result work area ! 19079: movab cfp$f(r10)[r7],r10 # point to first result character ! 19080: jsb sbmvc # move chars to result string ! 19081: movl r8,r9 # restore result pointer ! 19082: jmp gts29 # jump to exit ! 19083: #page ! 19084: # ! 19085: # GTSTG (CONTINUED) ! 19086: # ! 19087: # HERE TO CONVERT A REAL ! 19088: # ! 19089: gts10: movf 4*rcval(r9),r2 # load real ! 19090: clrl gtssf # reset negative flag ! 19091: tstf r2 # skip if zero ! 19092: bneq 0f ! 19093: jmp gts31 ! 19094: 0: ! 19095: tstf r2 # jump if real is positive ! 19096: bgeq gts11 ! 19097: movl $num01,gtssf # else set negative flag ! 19098: mnegf r2,r2 # and get absolute value of real ! 19099: # ! 19100: # NOW SCALE THE REAL TO THE RANGE (0.1 LE X LT 1.0) ! 19101: # ! 19102: gts11: movl intv0,r5 # initialize exponent to zero ! 19103: # ! 19104: # LOOP TO SCALE UP IN STEPS OF 10**10 ! 19105: # ! 19106: gts12: movf r2,gtsrs # save real value ! 19107: subf2 reap1,r2 # subtract 0.1 to compare ! 19108: tstf r2 # jump if scale up not required ! 19109: bgeq gts13 ! 19110: movf gtsrs,r2 # else reload value ! 19111: mulf2 reatt,r2 # multiply by 10**10 ! 19112: subl2 intvt,r5 # decrement exponent by 10 ! 19113: jmp gts12 # loop back to test again ! 19114: # ! 19115: # TEST FOR SCALE DOWN REQUIRED ! 19116: # ! 19117: gts13: movf gtsrs,r2 # reload value ! 19118: subf2 reav1,r2 # subtract 1.0 ! 19119: tstf r2 # jump if no scale down required ! 19120: blss gts17 ! 19121: movf gtsrs,r2 # else reload value ! 19122: # ! 19123: # LOOP TO SCALE DOWN IN STEPS OF 10**10 ! 19124: # ! 19125: gts14: subf2 reatt,r2 # subtract 10**10 to compare ! 19126: tstf r2 # jump if large step not required ! 19127: blss gts15 ! 19128: movf gtsrs,r2 # else restore value ! 19129: divf2 reatt,r2 # divide by 10**10 ! 19130: movf r2,gtsrs # store new value ! 19131: addl2 intvt,r5 # increment exponent by 10 ! 19132: jmp gts14 # loop back ! 19133: #page ! 19134: # ! 19135: # GTSTG (CONTINUED) ! 19136: # ! 19137: # AT THIS POINT WE HAVE (1.0 LE X LT 10**10) ! 19138: # COMPLETE SCALING WITH POWERS OF TEN TABLE ! 19139: # ! 19140: gts15: movl $reav1,r9 # point to powers of ten table ! 19141: # ! 19142: # LOOP TO LOCATE CORRECT ENTRY IN TABLE ! 19143: # ! 19144: gts16: movf gtsrs,r2 # reload value ! 19145: addl2 intv1,r5 # increment exponent ! 19146: addl2 $4*cfp$r,r9 # point to next entry in table ! 19147: subf2 (r9),r2 # subtract it to compare ! 19148: tstf r2 # loop till we find a larger entry ! 19149: bgeq gts16 ! 19150: movf gtsrs,r2 # then reload the value ! 19151: divf2 (r9),r2 # and complete scaling ! 19152: movf r2,gtsrs # store value ! 19153: # ! 19154: # WE ARE NOW SCALED, SO ROUND BY ADDING 0.5 * 10**(-CFP$S) ! 19155: # ! 19156: gts17: movf gtsrs,r2 # get value again ! 19157: addf2 gtsrn,r2 # add rounding factor ! 19158: movf r2,gtsrs # store result ! 19159: # ! 19160: # THE ROUNDING OPERATION MAY HAVE PUSHED US UP PAST ! 19161: # 1.0 AGAIN, SO CHECK ONE MORE TIME. ! 19162: # ! 19163: subf2 reav1,r2 # subtract 1.0 to compare ! 19164: tstf r2 # skip if ok ! 19165: blss gts18 ! 19166: addl2 intv1,r5 # else increment exponent ! 19167: movf gtsrs,r2 # reload value ! 19168: divf2 reavt,r2 # divide by 10.0 to rescale ! 19169: jmp gts19 # jump to merge ! 19170: # ! 19171: # HERE IF ROUNDING DID NOT MUCK UP SCALING ! 19172: # ! 19173: gts18: movf gtsrs,r2 # reload rounded value ! 19174: #page ! 19175: # ! 19176: # GTSTG (CONTINUED) ! 19177: # ! 19178: # NOW WE HAVE COMPLETED THE SCALING AS FOLLOWS ! 19179: # ! 19180: # (IA) SIGNED EXPONENT ! 19181: # (RA) SCALED REAL (ABSOLUTE VALUE) ! 19182: # ! 19183: # IF THE EXPONENT IS NEGATIVE OR GREATER THAN CFP$S, THEN ! 19184: # WE CONVERT THE NUMBER IN THE FORM. ! 19185: # ! 19186: # (NEG SIGN) 0 . (CPF$S DIGITS) E (EXP SIGN) (EXP DIGITS) ! 19187: # ! 19188: # IF THE EXPONENT IS POSITIVE AND LESS THAN OR EQUAL TO ! 19189: # CFP$S, THE NUMBER IS CONVERTED IN THE FORM. ! 19190: # ! 19191: # (NEG SIGN) (EXPONENT DIGITS) . (CFP$S-EXPONENT DIGITS) ! 19192: # ! 19193: # IN BOTH CASES, THE FORMATS OBTAINED FROM THE ABOVE ! 19194: # RULES ARE MODIFIED BY DELETING TRAILING ZEROS AFTER THE ! 19195: # DECIMAL POINT. THERE ARE NO LEADING ZEROS IN THE EXPONENT ! 19196: # AND THE EXPONENT SIGN IS ALWAYS PRESENT. ! 19197: # ! 19198: gts19: movl $cfp$s,r10 # set num dec digits = cfp$s ! 19199: movl $ch$mn,gtses # set exponent sign negative ! 19200: tstl r5 # all set if exponent is negative ! 19201: blss gts21 ! 19202: movl r5,r6 # else fetch exponent ! 19203: cmpl r6,$cfp$s # skip if we can use special format ! 19204: blequ gts20 ! 19205: movl r6,r5 # else restore exponent ! 19206: mnegl r5,r5 # set negative for cvd ! 19207: movl $ch$pl,gtses # set plus sign for exponent sign ! 19208: jmp gts21 # jump to generate exponent ! 19209: # ! 19210: # HERE IF WE CAN USE THE FORMAT WITHOUT AN EXPONENT ! 19211: # ! 19212: gts20: subl2 r6,r10 # compute digits after decimal point ! 19213: movl intv0,r5 # reset exponent to zero ! 19214: #page ! 19215: # ! 19216: # GTSTG (CONTINUED) ! 19217: # ! 19218: # MERGE HERE AS FOLLOWS ! 19219: # ! 19220: # (IA) EXPONENT ABSOLUTE VALUE ! 19221: # GTSES CHARACTER FOR EXPONENT SIGN ! 19222: # (RA) POSITIVE FRACTION ! 19223: # (XL) NUMBER OF DIGITS AFTER DEC POINT ! 19224: # ! 19225: gts21: movl gtswk,r9 # point to work area ! 19226: movl $nstmx,r7 # set character ctr to max length ! 19227: movab cfp$f(r9)[r7],r9# prepare to store (right to left) ! 19228: tstl r5 # skip exponent if it is zero ! 19229: beql gts23 ! 19230: # ! 19231: # LOOP TO GENERATE DIGITS OF EXPONENT ! 19232: # ! 19233: gts22: ashq $-32,r4,r4 # convert a digit into wa ! 19234: ediv $10,r4,r5,r6 ! 19235: mnegl r6,r6 ! 19236: bisb2 $0x30,r6 ! 19237: movb r6,-(r9) # store in work area ! 19238: decl r7 # decrement counter ! 19239: tstl r5 # loop back if more digits to go ! 19240: bneq gts22 ! 19241: # ! 19242: # HERE GENERATE EXPONENT SIGN AND E ! 19243: # ! 19244: movl gtses,r6 # load exponent sign ! 19245: movb r6,-(r9) # store in work area ! 19246: movl $ch$le,r6 # get character letter e ! 19247: movb r6,-(r9) # store in work area ! 19248: subl2 $num02,r7 # decrement counter for sign and e ! 19249: # ! 19250: # HERE TO GENERATE THE FRACTION ! 19251: # ! 19252: gts23: mulf2 gtssc,r2 # convert real to integer (10**cfp$s) ! 19253: cvtfl r2,r5 # get integer (overflow impossible) ! 19254: mnegl r5,r5 # negate as required by cvd ! 19255: # ! 19256: # LOOP TO SUPPRESS TRAILING ZEROS ! 19257: # ! 19258: gts24: tstl r10 # jump if no digits left to do ! 19259: beqlu gts27 ! 19260: ashq $-32,r4,r4 # else convert one digit ! 19261: ediv $10,r4,r5,r6 ! 19262: mnegl r6,r6 ! 19263: bisb2 $0x30,r6 ! 19264: cmpl r6,$ch$d0 # jump if not a zero ! 19265: bnequ gts26 ! 19266: decl r10 # decrement counter ! 19267: jmp gts24 # loop back for next digit ! 19268: #page ! 19269: # ! 19270: # GTSTG (CONTINUED) ! 19271: # ! 19272: # LOOP TO GENERATE DIGITS AFTER DECIMAL POINT ! 19273: # ! 19274: gts25: ashq $-32,r4,r4 # convert a digit into wa ! 19275: ediv $10,r4,r5,r6 ! 19276: mnegl r6,r6 ! 19277: bisb2 $0x30,r6 ! 19278: # ! 19279: # MERGE HERE FIRST TIME ! 19280: # ! 19281: gts26: movb r6,-(r9) # store digit ! 19282: decl r7 # decrement counter ! 19283: decl r10 # decrement counter ! 19284: tstl r10 # loop back if more to go ! 19285: bnequ gts25 ! 19286: # ! 19287: # HERE GENERATE THE DECIMAL POINT ! 19288: # ! 19289: gts27: movl $ch$dt,r6 # load decimal point ! 19290: movb r6,-(r9) # store in work area ! 19291: decl r7 # decrement counter ! 19292: # ! 19293: # HERE GENERATE THE DIGITS BEFORE THE DECIMAL POINT ! 19294: # ! 19295: gts28: ashq $-32,r4,r4 # convert a digit into wa ! 19296: ediv $10,r4,r5,r6 ! 19297: mnegl r6,r6 ! 19298: bisb2 $0x30,r6 ! 19299: movb r6,-(r9) # store in work area ! 19300: decl r7 # decrement counter ! 19301: tstl r5 # loop back if more to go ! 19302: bneq gts28 ! 19303: #csc r9 # complete store characters ! 19304: jmp gts08 # else jump back to exit ! 19305: # ! 19306: # EXIT POINT AFTER SUCCESSFUL CONVERSION ! 19307: # ! 19308: gts29: movl (sp)+,r10 # restore xl ! 19309: addl2 $4,sp # pop argument ! 19310: movl gtsvb,r7 # restore wb ! 19311: movl gtsvc,r8 # restore wc ! 19312: # ! 19313: # MERGE HERE IF NO CONVERSION REQUIRED ! 19314: # ! 19315: gts30: movl 4*sclen(r9),r6 # load string length ! 19316: addl3 $4*1,gtstg_s,r11 # return to caller ! 19317: jmp (r11) ! 19318: # ! 19319: # HERE TO RETURN STRING FOR REAL ZERO ! 19320: # ! 19321: gts31: movl $scre0,r10 # point to string ! 19322: movl $num02,r6 # 2 chars ! 19323: clrl r7 # zero offset ! 19324: jsb sbstr # copy string ! 19325: jmp gts29 # return ! 19326: #page ! 19327: # ! 19328: # HERE TO CONVERT A BUFFER BLOCK ! 19329: # ! 19330: gts32: movl r9,r10 # copy arg ptr ! 19331: movl 4*bclen(r10),r6 # get size to allocate ! 19332: tstl r6 # if null then return null ! 19333: beqlu gts33 ! 19334: jsb alocs # allocate string frame ! 19335: movl r9,r7 # save string ptr ! 19336: movl 4*sclen(r9),r6 # get length to move ! 19337: movab 3+(4*0)(r6),r6 # get as multiple of word size ! 19338: bicl2 $3,r6 ! 19339: movl 4*bcbuf(r10),r10# point to bfblk ! 19340: addl2 $4*scsi$,r9 # point to start of character area ! 19341: addl2 $4*bfsi$,r10 # point to start of buffer chars ! 19342: jsb sbmvw # copy words ! 19343: movl r7,r9 # restore scblk ptr ! 19344: jmp gts29 # exit with scblk ! 19345: # ! 19346: # HERE WHEN NULL BUFFER IS BEING CONVERTED ! 19347: # ! 19348: gts33: movl $nulls,r9 # point to null ! 19349: jmp gts29 # exit with null ! 19350: #enp # end procedure gtstg ! 19351: #page ! 19352: # ! 19353: # GTVAR -- GET VARIABLE FOR I/O/TRACE ASSOCIATION ! 19354: # ! 19355: # GTVAR IS USED TO POINT TO AN ACTUAL VARIABLE LOCATION ! 19356: # FOR THE DETACH,INPUT,OUTPUT,TRACE,STOPTR SYSTEM FUNCTIONS ! 19357: # ! 19358: # (XR) ARGUMENT TO FUNCTION ! 19359: # JSR GTVAR CALL TO LOCATE VARIABLE POINTER ! 19360: # PPM LOC TRANSFER LOC IF NOT OK VARIABLE ! 19361: # (XL,WA) NAME BASE,OFFSET OF VARIABLE ! 19362: # (XR,RA) DESTROYED ! 19363: # (WB,WC) DESTROYED (CONVERT ERROR ONLY) ! 19364: # (XR) INPUT ARG (CONVERT ERROR ONLY) ! 19365: # ! 19366: gtvar: #prc # entry point ! 19367: cmpl (r9),$b$nml # jump if not a name ! 19368: bnequ gtvr2 ! 19369: movl 4*nmofs(r9),r6 # else load name offset ! 19370: movl 4*nmbas(r9),r10 # load name base ! 19371: cmpl (r10),$b$evt # error if expression variable ! 19372: beqlu gtvr1 ! 19373: cmpl (r10),$b$kvt # all ok if not keyword variable ! 19374: bnequ gtvr3 ! 19375: # ! 19376: # HERE ON CONVERSION ERROR ! 19377: # ! 19378: gtvr1: movl (sp)+,r11 # take convert error exit ! 19379: jmp *(r11)+ ! 19380: # ! 19381: # HERE IF NOT A NAME, TRY CONVERT TO NATURAL VARIABLE ! 19382: # ! 19383: gtvr2: movl r8,gtvrc # save wc ! 19384: jsb gtnvr # locate vrblk if possible ! 19385: .long gtvr1 # jump if convert error ! 19386: movl r9,r10 # else copy vrblk name base ! 19387: movl $4*vrval,r6 # and set offset ! 19388: movl gtvrc,r8 # restore wc ! 19389: # ! 19390: # HERE FOR NAME OBTAINED ! 19391: # ! 19392: gtvr3: cmpl r10,state # all ok if not natural variable ! 19393: bgequ gtvr4 ! 19394: cmpl 4*vrsto(r10),$b$vre # error if protected variable ! 19395: beqlu gtvr1 ! 19396: # ! 19397: # COMMON EXIT POINT ! 19398: # ! 19399: gtvr4: addl2 $4*1,(sp) # return to caller ! 19400: rsb ! 19401: #enp # end procedure gtvar ! 19402: #page ! 19403: # ! 19404: # HASHS -- COMPUTE HASH INDEX FOR STRING ! 19405: # ! 19406: # HASHS IS USED TO CONVERT A STRING TO A UNIQUE INTEGER ! 19407: # VALUE. THE RESULTING HASH VALUE IS A POSITIVE INTEGER ! 19408: # IN THE RANGE 0 TO CFP$M ! 19409: # ! 19410: # (XR) STRING TO BE HASHED ! 19411: # JSR HASHS CALL TO HASH STRING ! 19412: # (IA) HASH VALUE ! 19413: # (XR,WB,WC) DESTROYED ! 19414: # ! 19415: # THE HASH FUNCTION USED IS AS FOLLOWS. ! 19416: # ! 19417: # START WITH THE LENGTH OF THE STRING (SGD07) ! 19418: # ! 19419: # TAKE THE FIRST E$HNW WORDS OF THE CHARACTERS FROM ! 19420: # THE STRING OR ALL THE WORDS IF FEWER THAN E$HNW. ! 19421: # ! 19422: # COMPUTE THE EXCLUSIVE OR OF ALL THESE WORDS TREATING ! 19423: # THEM AS ONE WORD BIT STRING VALUES. ! 19424: # ! 19425: # MOVE THE RESULT AS AN INTEGER WITH THE MTI INSTRUCTION. ! 19426: # ! 19427: hashs: #prc # entry point ! 19428: movl 4*sclen(r9),r8 # load string length in characters ! 19429: movl r8,r7 # initialize with length ! 19430: tstl r8 # jump if null string ! 19431: beqlu hshs3 ! 19432: movab 3+(4*0)(r8),r8 # else get number of words of chars ! 19433: ashl $-2,r8,r8 ! 19434: addl2 $4*schar,r9 # point to characters of string ! 19435: cmpl r8,$e$hnw # use whole string if short ! 19436: blequ hshs1 ! 19437: movl $e$hnw,r8 # else set to involve first e$hnw wds ! 19438: # ! 19439: # HERE WITH COUNT OF WORDS TO CHECK IN WC ! 19440: # ! 19441: hshs1: # set counter to control loop ! 19442: # ! 19443: # LOOP TO COMPUTE EXCLUSIVE OR ! 19444: # ! 19445: hshs2: xorl2 (r9)+,r7 # exclusive or next word of chars ! 19446: sobgtr r8,hshs2 # loop till all processed ! 19447: # ! 19448: # MERGE HERE WITH EXCLUSIVE OR IN WB ! 19449: # ! 19450: hshs3: #zgb r7 # zeroise undefined bits ! 19451: mcoml bitsm,r11 # ensure in range 0 to cfp$m ! 19452: bicl2 r11,r7 ! 19453: movl r7,r5 # move result as integer ! 19454: clrl r9 # clear garbage value in xr ! 19455: rsb # return to hashs caller ! 19456: #enp # end procedure hashs ! 19457: #page ! 19458: # ! 19459: # ICBLD -- BUILD INTEGER BLOCK ! 19460: # ! 19461: # (IA) INTEGER VALUE FOR ICBLK ! 19462: # JSR ICBLD CALL TO BUILD INTEGER BLOCK ! 19463: # (XR) POINTER TO RESULT ICBLK ! 19464: # (WA) DESTROYED ! 19465: # ! 19466: icbld: #prc # entry point ! 19467: movl r5,r9 # copy small integers ! 19468: bgeq 0f ! 19469: jmp icbl1 ! 19470: 0: ! 19471: cmpl r9,$num02 # jump if 0,1 or 2 ! 19472: blequ icbl3 ! 19473: # ! 19474: # CONSTRUCT ICBLK ! 19475: # ! 19476: icbl1: movl dnamp,r9 # load pointer to next available loc ! 19477: addl2 $4*icsi$,r9 # point past new icblk ! 19478: cmpl r9,dname # jump if there is room ! 19479: blequ icbl2 ! 19480: movl $4*icsi$,r6 # else load length of icblk ! 19481: jsb alloc # use standard allocator to get block ! 19482: addl2 r6,r9 # point past block to merge ! 19483: # ! 19484: # MERGE HERE WITH XR POINTING PAST THE BLOCK OBTAINED ! 19485: # ! 19486: icbl2: movl r9,dnamp # set new pointer ! 19487: subl2 $4*icsi$,r9 # point back to start of block ! 19488: movl $b$icl,(r9) # store type word ! 19489: movl r5,4*icval(r9) # store integer value in icblk ! 19490: rsb # return to icbld caller ! 19491: # ! 19492: # OPTIMISE BY NOT BUILDING ICBLKS FOR SMALL INTEGERS ! 19493: # ! 19494: icbl3: moval 0[r9],r9 # convert integer to offset ! 19495: movl l^intab(r9),r9 # point to pre-built icblk ! 19496: rsb # return ! 19497: #enp # end procedure icbld ! 19498: #page ! 19499: # ! 19500: # IDENT -- COMPARE TWO VALUES ! 19501: # ! 19502: # IDENT COMPARES TWO VALUES IN THE SENSE OF THE IDENT ! 19503: # DIFFER FUNCTIONS AVAILABLE AT THE SNOBOL LEVEL. ! 19504: # ! 19505: # (XR) FIRST ARGUMENT ! 19506: # (XL) SECOND ARGUMENT ! 19507: # JSR IDENT CALL TO COMPARE ARGUMENTS ! 19508: # PPM LOC TRANSFER LOC IF IDENT ! 19509: # (NORMAL RETURN IF DIFFER) ! 19510: # (XR,XL,WC,RA) DESTROYED ! 19511: # ! 19512: ident: #prc # entry point ! 19513: cmpl r9,r10 # jump if same pointer (ident) ! 19514: bnequ 0f ! 19515: jmp iden7 ! 19516: 0: ! 19517: movl (r9),r8 # else load arg 1 type word ! 19518: cmpl r8,(r10) # differ if arg 2 type word differ ! 19519: bnequ iden1 ! 19520: cmpl r8,$b$scl # jump if strings ! 19521: beqlu iden2 ! 19522: cmpl r8,$b$icl # jump if integers ! 19523: beqlu iden4 ! 19524: cmpl r8,$b$rcl # jump if reals ! 19525: beqlu iden5 ! 19526: cmpl r8,$b$nml # jump if names ! 19527: beqlu iden6 ! 19528: # ! 19529: # FOR ALL OTHER DATATYPES, MUST BE DIFFER IF XR NE XL ! 19530: # ! 19531: # MERGE HERE FOR DIFFER ! 19532: # ! 19533: iden1: addl2 $4*1,(sp) # take differ exit ! 19534: rsb ! 19535: # ! 19536: # HERE FOR STRINGS, IDENT ONLY IF LENGTHS AND CHARS SAME ! 19537: # ! 19538: iden2: movl 4*sclen(r9),r8 # load arg 1 length ! 19539: cmpl r8,4*sclen(r10) # differ if lengths differ ! 19540: bnequ iden1 ! 19541: movab 3+(4*0)(r8),r8 # get number of words in strings ! 19542: ashl $-2,r8,r8 ! 19543: addl2 $4*schar,r9 # point to chars of arg 1 ! 19544: addl2 $4*schar,r10 # point to chars of arg 2 ! 19545: # set loop counter ! 19546: # ! 19547: # LOOP TO COMPARE CHARACTERS. NOTE THAT WA CANNOT BE ZERO ! 19548: # SINCE ALL NULL STRINGS POINT TO NULLS AND GIVE XL=XR. ! 19549: # ! 19550: iden3: cmpl (r9),(r10) # differ if chars do not match ! 19551: bnequ iden8 ! 19552: addl2 $4,r9 # else bump arg one pointer ! 19553: addl2 $4,r10 # bump arg two pointer ! 19554: sobgtr r8,iden3 # loop back till all checked ! 19555: #page ! 19556: # ! 19557: # IDENT (CONTINUED) ! 19558: # ! 19559: # HERE TO EXIT FOR CASE OF TWO IDENT STRINGS ! 19560: # ! 19561: clrl r10 # clear garbage value in xl ! 19562: clrl r9 # clear garbage value in xr ! 19563: movl (sp)+,r11 # take ident exit ! 19564: jmp *(r11)+ ! 19565: # ! 19566: # HERE FOR INTEGERS, IDENT IF SAME VALUES ! 19567: # ! 19568: iden4: movl 4*icval(r9),r5 # load arg 1 ! 19569: subl2 4*icval(r10),r5 # subtract arg 2 to compare ! 19570: bvs iden1 ! 19571: tstl r5 # differ if result is not zero ! 19572: bneq iden1 ! 19573: movl (sp)+,r11 # take ident exit ! 19574: jmp *(r11)+ ! 19575: # ! 19576: # HERE FOR REALS, IDENT IF SAME VALUES ! 19577: # ! 19578: iden5: movf 4*rcval(r9),r2 # load arg 1 ! 19579: subf2 4*rcval(r10),r2 # subtract arg 2 to compare ! 19580: bvs iden1 ! 19581: tstf r2 # differ if result is not zero ! 19582: bneq iden1 ! 19583: movl (sp)+,r11 # take ident exit ! 19584: jmp *(r11)+ ! 19585: # ! 19586: # HERE FOR NAMES, IDENT IF BASES AND OFFSETS SAME ! 19587: # ! 19588: iden6: cmpl 4*nmofs(r9),4*nmofs(r10) # differ if different offset ! 19589: bnequ iden1 ! 19590: cmpl 4*nmbas(r9),4*nmbas(r10) # differ if different base ! 19591: bnequ iden1 ! 19592: # ! 19593: # MERGE HERE TO SIGNAL IDENT FOR IDENTICAL POINTERS ! 19594: # ! 19595: iden7: movl (sp)+,r11 # take ident exit ! 19596: jmp *(r11)+ ! 19597: # ! 19598: # HERE FOR DIFFER STRINGS ! 19599: # ! 19600: iden8: clrl r9 # clear garbage ptr in xr ! 19601: clrl r10 # clear garbage ptr in xl ! 19602: addl2 $4*1,(sp) # return to caller (differ) ! 19603: rsb ! 19604: #enp # end procedure ident ! 19605: #page ! 19606: # ! 19607: # INOUT - USED TO INITIALISE INPUT AND OUTPUT VARIABLES ! 19608: # ! 19609: # (XL) POINTER TO VBL NAME STRING ! 19610: # (WB) TRBLK TYPE ! 19611: # JSR INOUT CALL TO PERFORM INITIALISATION ! 19612: # (XL) VRBLK PTR ! 19613: # (XR) TRBLK PTR ! 19614: # (WA,WC) DESTROYED ! 19615: # ! 19616: # NOTE THAT TRTER (= TRTRF) FIELD OF STANDARD I/O VARIABLES ! 19617: # POINTS TO CORRESPONDING SVBLK NOT TO A TRBLK AS IS THE ! 19618: # CASE FOR ORDINARY VARIABLES. ! 19619: # ! 19620: inout: #prc # entry point ! 19621: movl r7,-(sp) # stack trblk type ! 19622: movl 4*sclen(r10),r6 # get name length ! 19623: clrl r7 # point to start of name ! 19624: jsb sbstr # build a proper scblk ! 19625: jsb gtnvr # build vrblk ! 19626: .long invalid$ # no error return ! 19627: movl r9,r8 # save vrblk pointer ! 19628: movl (sp)+,r7 # get trter field ! 19629: clrl r10 # zero trfpt ! 19630: jsb trbld # build trblk ! 19631: movl r8,r10 # recall vrblk pointer ! 19632: movl 4*vrsvp(r10),4*trter(r9) # store svblk pointer ! 19633: movl r9,4*vrval(r10) # store trblk ptr in vrblk ! 19634: movl $b$vra,4*vrget(r10) # set trapped access ! 19635: movl $b$vrv,4*vrsto(r10) # set trapped store ! 19636: rsb # return to caller ! 19637: #enp # end procedure inout ! 19638: #page ! 19639: # ! 19640: # INSBF -- INSERT STRING IN BUFFER ! 19641: # ! 19642: # THIS ROUTINE WILL REPLACE A SECTION OF A BUFFER WITH THE ! 19643: # CONTENTS OF A GIVEN STRING. IF THE LENGTH OF THE ! 19644: # SECTION TO BE REPLACED IS DIFFERENT THAN THE LENGTH OF ! 19645: # THE GIVEN STRING, AND THE REPLACEMENT IS NOT AN APPEND, ! 19646: # THEN THE UPPER SECTION OF THE BUFFER IS SHIFTED UP OR ! 19647: # DOWN TO CREATE THE PROPER SPACE FOR THE INSERT. ! 19648: # ! 19649: # (XR) POINTER TO BFBLK ! 19650: # (XL) OBJECT WHICH IS STRING CONVERTABLE ! 19651: # (WA) OFFSET OF START OF INSERT IN (XR) ! 19652: # (WB) LENGTH OF SECTION IN (XR) REPLACED ! 19653: # JSR INSBF CALL TO INSERT CHARACTERS IN BUFFER ! 19654: # PPM LOC THREAD IF (XR) NOT CONVERTABLE ! 19655: # PPM LOC THREAD IF INSERT NOT POSSIBLE ! 19656: # ! 19657: # THE SECOND ALTERNATE EXIT IS TAKEN IF THE INSERT WOULD ! 19658: # OVERFLOW THE BUFFER, OR IF THE INSERT IS OUT PAST THE ! 19659: # DEFINED END OF THE BUFFER AS GIVEN. ! 19660: # ! 19661: insbf: #prc # entry point ! 19662: movl r6,inssa # save entry wa ! 19663: movl r7,inssb # save entry wb ! 19664: movl r8,inssc # save entry wc ! 19665: addl2 r7,r6 # add to get offset past replace part ! 19666: movl r6,insab # save wa+wb ! 19667: movl 4*bclen(r9),r8 # get current defined length ! 19668: cmpl inssa,r8 # fail if start offset too big ! 19669: blequ 0f ! 19670: jmp ins07 ! 19671: 0: ! 19672: cmpl r6,r8 # fail if final offset too big ! 19673: blequ 0f ! 19674: jmp ins07 ! 19675: 0: ! 19676: movl r10,-(sp) # save entry xl ! 19677: movl r9,-(sp) # save bcblk ptr ! 19678: movl r10,-(sp) # stack again for gtstg ! 19679: jsb gtstg # call to convert to string ! 19680: .long ins05 # take string convert err exit ! 19681: movl r9,r10 # save string ptr ! 19682: movl (sp),r9 # restore bcblk ptr ! 19683: addl2 r8,r6 # add buffer len to string len ! 19684: subl2 inssb,r6 # bias out component being replaced ! 19685: movl 4*bcbuf(r9),r9 # point to bfblk ! 19686: cmpl r6,4*bfalc(r9) # fail if result exceeds allocation ! 19687: blequ 0f ! 19688: jmp ins06 ! 19689: 0: ! 19690: movl (sp),r9 # restore bcblk ptr ! 19691: movl r8,r6 # get buffer length ! 19692: subl2 insab,r6 # subtract to get shift length ! 19693: addl2 4*sclen(r10),r8 # add length of new ! 19694: subl2 inssb,r8 # subtract old to get total new len ! 19695: movl 4*bclen(r9),r7 # get old bclen ! 19696: movl r8,4*bclen(r9) # stuff new length ! 19697: tstl r6 # skip shift if nothing to do ! 19698: bnequ 0f ! 19699: jmp ins04 ! 19700: 0: ! 19701: cmpl inssb,4*sclen(r10) # skip shift if lengths match ! 19702: bnequ 0f ! 19703: jmp ins04 ! 19704: 0: ! 19705: movl 4*bcbuf(r9),r9 # point to bfblk ! 19706: movl r10,-(sp) # save scblk ptr ! 19707: cmpl inssb,4*sclen(r10) # brn if shft is for more room ! 19708: blequ ins01 ! 19709: #page ! 19710: # ! 19711: # INSBF (CONTINUED) ! 19712: # ! 19713: # WE ARE SHIFTING THE UPPER SEGMENT DOWN TO COMPACT ! 19714: # THE BUFFER. (THE STRING LENGTH IS SMALLER THAN THE ! 19715: # SEGMENT BEING REPLACED.) REGISTERS ARE SET AS: ! 19716: # ! 19717: # (WA) MOVE (SHIFT DOWN) LENGTH ! 19718: # (WB) OLD BCLEN ! 19719: # (WC) NEW BCLEN ! 19720: # (XR) BFBLK PTR ! 19721: # (XL),(XS) SCBLK PTR ! 19722: # ! 19723: movl inssa,r7 # get offset to insert ! 19724: addl2 4*sclen(r10),r7 # add insert length to get dest off ! 19725: movl r9,r10 # make copy ! 19726: movl insab,r11 # [get in scratch register] ! 19727: movab cfp$f(r10)[r11],r10 # prepare source for move ! 19728: movab cfp$f(r9)[r7],r9# prepare destination reg for move ! 19729: jsb sbmvc # move em out ! 19730: jmp ins02 # branch to pad ! 19731: # ! 19732: # WE ARE SHIFTING THE UPPER SEGMENT UP TO EXPAND ! 19733: # THE BUFFER. (THE STRING LENGTH IS LARGER THAN THE ! 19734: # SEGMENT BEING REPLACED.) ! 19735: # ! 19736: ins01: movl r9,r10 # copy bfblk ptr ! 19737: movab cfp$f(r10)[r7],r10 # set source reg for move backwards ! 19738: movab cfp$f(r9)[r8],r9# set destination ptr for move ! 19739: jsb sbmcb # move backwards (possible overlap) ! 19740: # ! 19741: # MERGE HERE AFTER MOVE TO ADJUST PADDING AT NEW BUFFER END ! 19742: # ! 19743: ins02: movl (sp)+,r10 # restore scblk ptr ! 19744: movl r8,r6 # copy new buffer end ! 19745: movab 3+(4*0)(r6),r6 # round out ! 19746: bicl2 $3,r6 ! 19747: subl2 r8,r6 # subtract to get remainder ! 19748: tstl r6 # no pad if already even boundary ! 19749: bnequ 0f ! 19750: jmp ins04 ! 19751: 0: ! 19752: movl (sp),r9 # get bcblk ptr ! 19753: movl 4*bcbuf(r9),r9 # get bfblk ptr ! 19754: movab cfp$f(r9)[r8],r9# prepare to pad ! 19755: clrl r7 # clear wb ! 19756: # load loop count ! 19757: # ! 19758: # LOOP HERE TO STUFF PAD CHARACTERS ! 19759: # ! 19760: ins03: movb r7,(r9)+ # stuff zero pad ! 19761: sobgtr r6,ins03 # branch for more ! 19762: #page ! 19763: # ! 19764: # INSBF (CONTINUED) ! 19765: # ! 19766: # MERGE HERE WHEN PADDING OK. NOW COPY IN THE INSERT ! 19767: # STRING TO THE HOLE. ! 19768: # ! 19769: ins04: movl (sp),r9 # get bcblk ptr ! 19770: movl 4*bcbuf(r9),r9 # get bfblk ptr ! 19771: movl 4*sclen(r10),r6 # get move length ! 19772: movab cfp$f(r10),r10 # prepare to copy from first char ! 19773: movl inssa,r11 # [get in scratch register] ! 19774: movab cfp$f(r9)[r11],r9# prepare to store in hole ! 19775: jsb sbmvc # copy the characters ! 19776: movl (sp)+,r9 # restore entry xr ! 19777: movl (sp)+,r10 # restore entry xl ! 19778: movl inssa,r6 # restore entry wa ! 19779: movl inssb,r7 # restore entry wb ! 19780: movl inssc,r8 # restore entry wc ! 19781: addl2 $4*2,(sp) # return to caller ! 19782: rsb ! 19783: # ! 19784: # HERE TO TAKE STRING CONVERT ERROR EXIT ! 19785: # ! 19786: ins05: movl (sp)+,r9 # restore entry xr ! 19787: movl (sp)+,r10 # restore entry xl ! 19788: movl inssa,r6 # restore entry wa ! 19789: movl inssb,r7 # restore entry wb ! 19790: movl inssc,r8 # restore entry wc ! 19791: movl (sp)+,r11 # alternate exit ! 19792: jmp *(r11)+ ! 19793: # ! 19794: # HERE FOR INVALID OFFSET OR LENGTH ! 19795: # ! 19796: ins06: movl (sp)+,r9 # restore entry xr ! 19797: movl (sp)+,r10 # restore entry xl ! 19798: # ! 19799: # MERGE FOR LENGTH FAILURE EXIT WITH STACK SET ! 19800: # ! 19801: ins07: movl inssa,r6 # restore entry wa ! 19802: movl inssb,r7 # restore entry wb ! 19803: movl inssc,r8 # restore entry wc ! 19804: addl3 $4*1,(sp)+,r11 # alternate exit ! 19805: jmp *(r11)+ ! 19806: #enp # end procedure insbf ! 19807: #page ! 19808: # ! 19809: # IOFCB -- GET INPUT/OUTPUT FCBLK POINTER ! 19810: # ! 19811: # USED BY ENDFILE, EJECT AND REWIND TO FIND THE FCBLK ! 19812: # (IF ANY) CORRESPONDING TO THEIR ARGUMENT. ! 19813: # ! 19814: # -(XS) ARGUMENT ! 19815: # JSR IOFCB CALL TO FIND FCBLK ! 19816: # PPM LOC ARG IS AN UNSUITABLE NAME ! 19817: # PPM LOC ARG IS NULL STRING ! 19818: # (XS) POPPED ! 19819: # (XL) PTR TO FILEARG1 VRBLK ! 19820: # (XR) ARGUMENT ! 19821: # (WA) FCBLK PTR OR 0 ! 19822: # (WB) DESTROYED ! 19823: # ! 19824: .data 1 ! 19825: iofcb_s: .long 0 ! 19826: .text 0 ! 19827: iofcb: movl (sp)+,iofcb_s # entry point ! 19828: jsb gtstg # get arg as string ! 19829: .long iofc2 # fail ! 19830: movl r9,r10 # copy string ptr ! 19831: jsb gtnvr # get as natural variable ! 19832: .long iofc3 # fail if null ! 19833: movl r10,r7 # copy string pointer again ! 19834: movl r9,r10 # copy vrblk ptr for return ! 19835: clrl r6 # in case no trblk found ! 19836: # ! 19837: # LOOP TO FIND FILE ARG1 TRBLK ! 19838: # ! 19839: iofc1: movl 4*vrval(r9),r9 # get possible trblk ptr ! 19840: cmpl (r9),$b$trt # fail if end of chain ! 19841: bnequ iofc2 ! 19842: cmpl 4*trtyp(r9),$trtfc # loop if not file arg trblk ! 19843: bnequ iofc1 ! 19844: movl 4*trfpt(r9),r6 # get fcblk ptr ! 19845: movl r7,r9 # copy arg ! 19846: addl3 $4*2,iofcb_s,r11 # return ! 19847: jmp (r11) ! 19848: # ! 19849: # FAIL RETURN ! 19850: # ! 19851: iofc2: movl iofcb_s,r11 # fail ! 19852: jmp *(r11)+ ! 19853: # ! 19854: # NULL ARG ! 19855: # ! 19856: iofc3: addl3 $4*1,iofcb_s,r11 # null arg return ! 19857: jmp *(r11)+ ! 19858: #enp # end procedure iofcb ! 19859: #page ! 19860: # ! 19861: # IOPPF -- PROCESS FILEARG2 FOR IOPUT ! 19862: # ! 19863: # (R$XSC) FILEARG2 PTR ! 19864: # JSR IOPPF CALL TO PROCESS FILEARG2 ! 19865: # (XL) FILEARG1 PTR ! 19866: # (XR) FILE ARG2 PTR ! 19867: # -(XS)..-(XS) FIELDS EXTRACTED FROM FILEARG2 ! 19868: # (WC) NO. OF FIELDS EXTRACTED ! 19869: # (WB) INPUT/OUTPUT FLAG ! 19870: # (WA) FCBLK PTR OR 0 ! 19871: # ! 19872: .data 1 ! 19873: ioppf_s: .long 0 ! 19874: .text 0 ! 19875: ioppf: movl (sp)+,ioppf_s # entry point ! 19876: clrl r7 # to count fields extracted ! 19877: # ! 19878: # LOOP TO EXTRACT FIELDS ! 19879: # ! 19880: iopp1: movl $iodel,r10 # get delimiter ! 19881: movl r10,r8 # copy it ! 19882: jsb xscan # get next field ! 19883: movl r9,-(sp) # stack it ! 19884: incl r7 # increment count ! 19885: tstl r6 # loop ! 19886: bnequ iopp1 ! 19887: movl r7,r8 # count of fields ! 19888: movl ioptt,r7 # i/o marker ! 19889: movl r$iof,r6 # fcblk ptr or 0 ! 19890: movl r$io2,r9 # file arg2 ptr ! 19891: movl r$io1,r10 # filearg1 ! 19892: jmp *ioppf_s # return ! 19893: #enp # end procedure ioppf ! 19894: #page ! 19895: # ! 19896: # IOPUT -- ROUTINE USED BY INPUT AND OUTPUT ! 19897: # ! 19898: # IOPUT SETS UP INPUT/OUTPUT ASSOCIATIONS. IT BUILDS ! 19899: # SUCH TRACE AND FILE CONTROL BLOCKS AS ARE NECESSARY AND ! 19900: # CALLS SYSFC,SYSIO TO PERFORM CHECKS ON THE ! 19901: # ARGUMENTS AND TO OPEN THE FILES. ! 19902: # ! 19903: # +-----------+ +---------------+ +-----------+ ! 19904: # +-.I I I I------.I =B$XRT I ! 19905: # I +-----------+ +---------------+ +-----------+ ! 19906: # I / / (R$FCB) I *4 I ! 19907: # I / / +-----------+ ! 19908: # I +-----------+ +---------------+ I I- ! 19909: # I I NAME +--.I =B$TRT I +-----------+ ! 19910: # I / / +---------------+ I I ! 19911: # I (FIRST ARG) I =TRTIN/=TRTOU I +-----------+ ! 19912: # I +---------------+ I ! 19913: # I I VALUE I I ! 19914: # I +---------------+ I ! 19915: # I I(TRTRF) 0 OR I--+ I ! 19916: # I +---------------+ I I ! 19917: # I I(TRFPT) 0 OR I----+ I ! 19918: # I +---------------+ I I I ! 19919: # I (I/O TRBLK) I I I ! 19920: # I +-----------+ I I I ! 19921: # I I I I I I ! 19922: # I +-----------+ I I I ! 19923: # I I I I I I ! 19924: # I +-----------+ +---------------+ I I I ! 19925: # I I +--.I =B$TRT I.-+ I I ! 19926: # I +-----------+ +---------------+ I I ! 19927: # I / / I =TRTFC I I I ! 19928: # I / / +---------------+ I I ! 19929: # I (FILEARG1 I VALUE I I I ! 19930: # I VRBLK) +---------------+ I I ! 19931: # I I(TRTRF) 0 OR I--+ I . ! 19932: # I +---------------+ I . +-----------+ ! 19933: # I I(TRFPT) 0 OR I------./ FCBLK / ! 19934: # I +---------------+ I +-----------+ ! 19935: # I (TRTRF) I ! 19936: # I I ! 19937: # I I ! 19938: # I +---------------+ I ! 19939: # I I =B$XRT I.-+ ! 19940: # I +---------------+ ! 19941: # I I *5 I ! 19942: # I +---------------+ ! 19943: # +------------------I I ! 19944: # +---------------+ +-----------+ ! 19945: # I(TRTRF) O OR I------.I =B$XRT I ! 19946: # +---------------+ +-----------+ ! 19947: # I NAME OFFSET I I ETC I ! 19948: # +---------------+ ! 19949: # (IOCHN - CHAIN OF NAME POINTERS) ! 19950: #page ! 19951: # ! 19952: # IOPUT (CONTINUED) ! 19953: # ! 19954: # NO ADDITIONAL TRAP BLOCKS ARE USED FOR STANDARD INPUT/OUT ! 19955: # FILES. OTHERWISE AN I/O TRAP BLOCK IS ATTACHED TO SECOND ! 19956: # ARG (FILEARG1) VRBLK. SEE DIAGRAM ABOVE FOR DETAILS OF ! 19957: # THE STRUCTURE BUILT. ! 19958: # ! 19959: # -(XS) 1ST ARG (VBL TO BE ASSOCIATED) ! 19960: # -(XS) 2ND ARG (FILE ARG1) ! 19961: # -(XS) 3RD ARG (FILE ARG2) ! 19962: # (WB) 0 FOR INPUT, 3 FOR OUTPUT ASSOC. ! 19963: # JSR IOPUT CALL FOR INPUT/OUTPUT ASSOCIATION ! 19964: # PPM LOC 3RD ARG NOT A STRING ! 19965: # PPM LOC 2ND ARG NOT A SUITABLE NAME ! 19966: # PPM LOC 1ST ARG NOT A SUITABLE NAME ! 19967: # PPM LOC INAPPROPRIATE FILE SPEC FOR I/O ! 19968: # PPM LOC I/O FILE DOES NOT EXIST ! 19969: # PPM LOC I/O FILE CANNOT BE READ/WRITTEN ! 19970: # (XS) POPPED ! 19971: # (XL,XR,WA,WB,WC) DESTROYED ! 19972: # ! 19973: .data 1 ! 19974: ioput_s: .long 0 ! 19975: .text 0 ! 19976: ioput: movl (sp)+,ioput_s # entry point ! 19977: clrl r$iot # in case no trtrf block used ! 19978: clrl r$iof # in case no fcblk alocated ! 19979: movl r7,ioptt # store i/o trace type ! 19980: jsb xscni # prepare to scan filearg2 ! 19981: .long iop13 # fail ! 19982: .long iopa0 # null file arg2 ! 19983: # ! 19984: iopa0: movl r9,r$io2 # keep file arg2 ! 19985: movl r6,r10 # copy length ! 19986: jsb gtstg # convert filearg1 to string ! 19987: .long iop14 # fail ! 19988: movl r9,r$io1 # keep filearg1 ptr ! 19989: jsb gtnvr # convert to natural variable ! 19990: .long iop00 # jump if null ! 19991: jmp iop04 # jump to process non-null args ! 19992: # ! 19993: # NULL FILEARG1 ! 19994: # ! 19995: iop00: tstl r10 # skip if both args null ! 19996: bnequ 0f ! 19997: jmp iop01 ! 19998: 0: ! 19999: jsb ioppf # process filearg2 ! 20000: jsb sysfc # call for filearg2 check ! 20001: .long iop16 # fail ! 20002: jmp iop11 # complete file association ! 20003: #page ! 20004: # ! 20005: # IOPUT (CONTINUED) ! 20006: # ! 20007: # HERE WITH 0 OR FCBLK PTR IN (XL) ! 20008: # ! 20009: iop01: movl ioptt,r7 # get trace type ! 20010: movl r$iot,r9 # get 0 or trtrf ptr ! 20011: jsb trbld # build trblk ! 20012: movl r9,r8 # copy trblk pointer ! 20013: movl (sp)+,r9 # get variable from stack ! 20014: jsb gtvar # point to variable ! 20015: .long iop15 # fail ! 20016: movl r10,r$ion # save name pointer ! 20017: movl r10,r9 # copy name pointer ! 20018: addl2 r6,r9 # point to variable ! 20019: subl2 $4*vrval,r9 # subtract offset,merge into loop ! 20020: # ! 20021: # LOOP TO END OF TRBLK CHAIN IF ANY ! 20022: # ! 20023: iop02: movl r9,r10 # copy blk ptr ! 20024: movl 4*vrval(r9),r9 # load ptr to next trblk ! 20025: cmpl (r9),$b$trt # jump if not trapped ! 20026: bnequ iop03 ! 20027: cmpl 4*trtyp(r9),ioptt# loop if not same assocn ! 20028: bnequ iop02 ! 20029: movl 4*trnxt(r9),r9 # get value and delete old trblk ! 20030: # ! 20031: # IOPUT (CONTINUED) ! 20032: # ! 20033: # STORE NEW ASSOCIATION ! 20034: # ! 20035: iop03: movl r8,4*vrval(r10) # link to this trblk ! 20036: movl r8,r10 # copy pointer ! 20037: movl r9,4*trnxt(r10) # store value in trblk ! 20038: movl r$ion,r9 # restore possible vrblk pointer ! 20039: movl r6,r7 # keep offset to name ! 20040: jsb setvr # if vrblk, set vrget,vrsto ! 20041: movl r$iot,r9 # get 0 or trtrf ptr ! 20042: tstl r9 # jump if trtrf block exists ! 20043: beqlu 0f ! 20044: jmp iop19 ! 20045: 0: ! 20046: addl3 $4*6,ioput_s,r11 # return to caller ! 20047: jmp (r11) ! 20048: # ! 20049: # NON STANDARD FILE ! 20050: # SEE IF AN FCBLK HAS ALREADY BEEN ALLOCATED. ! 20051: # ! 20052: iop04: clrl r6 # in case no fcblk found ! 20053: #page ! 20054: # ! 20055: # IOPUT (CONTINUED) ! 20056: # ! 20057: # SEARCH POSSIBLE TRBLK CHAIN TO PICK UP THE FCBLK ! 20058: # ! 20059: iop05: movl r9,r7 # remember blk ptr ! 20060: movl 4*vrval(r9),r9 # chain along ! 20061: cmpl (r9),$b$trt # jump if end of trblk chain ! 20062: bnequ iop06 ! 20063: cmpl 4*trtyp(r9),$trtfc # loop if more to go ! 20064: bnequ iop05 ! 20065: movl r9,r$iot # point to file arg1 trblk ! 20066: movl 4*trfpt(r9),r6 # get fcblk ptr from trblk ! 20067: # ! 20068: # WA = 0 OR FCBLK PTR ! 20069: # WB = PTR TO PRECEDING BLK TO WHICH ANY TRTRF BLOCK ! 20070: # FOR FILE ARG1 MUST BE CHAINED. ! 20071: # ! 20072: iop06: movl r6,r$iof # keep possible fcblk ptr ! 20073: movl r7,r$iop # keep preceding blk ptr ! 20074: jsb ioppf # process filearg2 ! 20075: jsb sysfc # see if fcblk required ! 20076: .long iop16 # fail ! 20077: tstl r6 # skip if no new fcblk wanted ! 20078: bnequ 0f ! 20079: jmp iop12 ! 20080: 0: ! 20081: cmpl r8,$num02 # jump if fcblk in dynamic ! 20082: blssu iop6a ! 20083: jsb alost # get it in static ! 20084: jmp iop6b # skip ! 20085: # ! 20086: # OBTAIN FCBLK IN DYNAMIC ! 20087: # ! 20088: iop6a: jsb alloc # get space for fcblk ! 20089: # ! 20090: # MERGE ! 20091: # ! 20092: iop6b: movl r9,r10 # point to fcblk ! 20093: movl r6,r7 # copy its length ! 20094: ashl $-2,r7,r7 # get count as words (sgd apr80) ! 20095: # loop counter ! 20096: # ! 20097: # CLEAR FCBLK ! 20098: # ! 20099: iop07: clrl (r9)+ # clear a word ! 20100: sobgtr r7,iop07 # loop ! 20101: cmpl r8,$num02 # skip if in static - dont set fields ! 20102: bnequ 0f ! 20103: jmp iop09 ! 20104: 0: ! 20105: movl $b$xnt,(r10) # store xnblk code in case ! 20106: movl r6,4*1(r10) # store length ! 20107: tstl r8 # jump if xnblk wanted ! 20108: beqlu 0f ! 20109: jmp iop09 ! 20110: 0: ! 20111: movl $b$xrt,(r10) # xrblk code requested ! 20112: # ! 20113: #page ! 20114: # IOPUT (CONTINUED) ! 20115: # ! 20116: # COMPLETE FCBLK INITIALISATION ! 20117: # ! 20118: iop09: movl r$iot,r9 # get possible trblk ptr ! 20119: movl r10,r$iof # store fcblk ptr ! 20120: tstl r9 # jump if trblk already found ! 20121: bnequ iop10 ! 20122: # ! 20123: # A NEW TRBLK IS NEEDED ! 20124: # ! 20125: movl $trtfc,r7 # trtyp for fcblk trap blk ! 20126: jsb trbld # make the block ! 20127: movl r9,r$iot # copy trtrf ptr ! 20128: movl r$iop,r10 # point to preceding blk ! 20129: movl 4*vrval(r10),4*vrval(r9) # copy value field to trblk ! 20130: movl r9,4*vrval(r10) # link new trblk into chain ! 20131: movl r10,r9 # point to predecessor blk ! 20132: jsb setvr # set trace intercepts ! 20133: movl 4*vrval(r9),r9 # recover trblk ptr ! 20134: # ! 20135: # XR IS PTR TO TRBLK, XL IS FCBLK PTR OR 0 ! 20136: # ! 20137: iop10: movl r$iof,4*trfpt(r9)# store fcblk ptr ! 20138: # ! 20139: # CALL SYSIO TO COMPLETE FILE ACCESSING ! 20140: # ! 20141: iop11: movl r$iof,r6 # copy fcblk ptr or 0 ! 20142: movl ioptt,r7 # get input/output flag ! 20143: movl r$io2,r9 # get file arg2 ! 20144: movl r$io1,r10 # get file arg1 ! 20145: jsb sysio # associate to the file ! 20146: .long iop17 # fail ! 20147: .long iop18 # fail ! 20148: tstl r$iot # not std input if non-null trtrf blk ! 20149: beqlu 0f ! 20150: jmp iop01 ! 20151: 0: ! 20152: tstl ioptt # jump if output ! 20153: beqlu 0f ! 20154: jmp iop01 ! 20155: 0: ! 20156: tstl r8 # no change to standard read length ! 20157: bnequ 0f ! 20158: jmp iop01 ! 20159: 0: ! 20160: movl r8,cswin # store new read length for std file ! 20161: jmp iop01 # merge to finish the task ! 20162: # ! 20163: # SYSFC MAY HAVE RETURNED A POINTER TO A PRIVATE FCBLK ! 20164: # ! 20165: iop12: tstl r10 # jump if private fcblk ! 20166: beqlu 0f ! 20167: jmp iop09 ! 20168: 0: ! 20169: jmp iop11 # finish the association ! 20170: # ! 20171: # FAILURE RETURNS ! 20172: # ! 20173: iop13: movl ioput_s,r11 # 3rd arg not a string ! 20174: jmp *(r11)+ ! 20175: iop14: addl3 $4*1,ioput_s,r11 # 2nd arg unsuitable ! 20176: jmp *(r11)+ ! 20177: iop15: addl3 $4*2,ioput_s,r11 # 1st arg unsuitable ! 20178: jmp *(r11)+ ! 20179: iop16: addl3 $4*3,ioput_s,r11 # file spec wrong ! 20180: jmp *(r11)+ ! 20181: iop17: addl3 $4*4,ioput_s,r11 # i/o file does not exist ! 20182: jmp *(r11)+ ! 20183: iop18: addl3 $4*5,ioput_s,r11 # i/o file cannot be read/written ! 20184: jmp *(r11)+ ! 20185: #page ! 20186: # ! 20187: # IOPUT (CONTINUED) ! 20188: # ! 20189: # ADD TO IOCHN CHAIN OF ASSSOCIATED VARIABLES UNLESS ALREAD ! 20190: # PRESENT. ! 20191: # ! 20192: iop19: movl r$ion,r8 # wc = name base, wb = name offset ! 20193: # ! 20194: # SEARCH LOOP ! 20195: # ! 20196: iop20: movl 4*trtrf(r9),r9 # next link of chain ! 20197: tstl r9 # not found ! 20198: beqlu iop21 ! 20199: cmpl r8,4*ionmb(r9) # no match ! 20200: bnequ iop20 ! 20201: cmpl r7,4*ionmo(r9) # exit if matched ! 20202: beqlu iop22 ! 20203: jmp iop20 # loop ! 20204: # ! 20205: # NOT FOUND ! 20206: # ! 20207: iop21: movl $4*num05,r6 # space needed ! 20208: jsb alloc # get it ! 20209: movl $b$xrt,(r9) # store xrblk code ! 20210: movl r6,4*1(r9) # store length ! 20211: movl r8,4*ionmb(r9) # store name base ! 20212: movl r7,4*ionmo(r9) # store name offset ! 20213: movl r$iot,r10 # point to trtrf blk ! 20214: movl 4*trtrf(r10),r6 # get ptr field contents ! 20215: movl r9,4*trtrf(r10) # store ptr to new block ! 20216: movl r6,4*trtrf(r9) # complete the linking ! 20217: # ! 20218: # INSERT FCBLK ON FCBLK CHAIN FOR SYSEJ, SYSXI ! 20219: # ! 20220: iop22: tstl r$iof # skip if no fcblk ! 20221: beqlu iop25 ! 20222: movl r$fcb,r10 # ptr to head of existing chain ! 20223: # ! 20224: # SEE IF FCBLK ALREADY ON CHAIN ! 20225: # ! 20226: iop23: tstl r10 # not on if end of chain ! 20227: beqlu iop24 ! 20228: cmpl 4*3(r10),r$iof # dont duplicate if find it ! 20229: beqlu iop25 ! 20230: movl 4*2(r10),r10 # get next link ! 20231: jmp iop23 # loop ! 20232: # ! 20233: # NOT FOUND SO ADD AN ENTRY FOR THIS FCBLK ! 20234: # ! 20235: iop24: movl $4*num04,r6 # space needed ! 20236: jsb alloc # get it ! 20237: movl $b$xrt,(r9) # store block code ! 20238: movl r6,4*1(r9) # store length ! 20239: movl r$fcb,4*2(r9) # store previous link in this node ! 20240: movl r$iof,4*3(r9) # store fcblk ptr ! 20241: movl r9,r$fcb # insert node into fcblk chain ! 20242: # ! 20243: # RETURN ! 20244: # ! 20245: iop25: addl3 $4*6,ioput_s,r11 # return to caller ! 20246: jmp (r11) ! 20247: #enp # end procedure ioput ! 20248: #page ! 20249: # ! 20250: # KTREX -- EXECUTE KEYWORD TRACE ! 20251: # ! 20252: # KTREX IS USED TO EXECUTE A POSSIBLE KEYWORD TRACE. IT ! 20253: # INCLUDES THE TEST ON TRACE AND TESTS FOR TRACE ACTIVE. ! 20254: # ! 20255: # (XL) PTR TO TRBLK (OR 0 IF UNTRACED) ! 20256: # JSR KTREX CALL TO EXECUTE KEYWORD TRACE ! 20257: # (XL,WA,WB,WC) DESTROYED ! 20258: # (RA) DESTROYED ! 20259: # ! 20260: ktrex: #prc # entry point (recursive) ! 20261: tstl r10 # immediate exit if keyword untraced ! 20262: beqlu ktrx3 ! 20263: tstl kvtra # immediate exit if trace = 0 ! 20264: beqlu ktrx3 ! 20265: decl kvtra # else decrement trace ! 20266: movl r9,-(sp) # save xr ! 20267: movl r10,r9 # copy trblk pointer ! 20268: movl 4*trkvr(r9),r10 # load vrblk pointer (nmbas) ! 20269: movl $4*vrval,r6 # set name offset ! 20270: tstl 4*trfnc(r9) # jump if print trace ! 20271: beqlu ktrx1 ! 20272: jsb trxeq # else execute full trace ! 20273: jmp ktrx2 # and jump to exit ! 20274: # ! 20275: # HERE FOR PRINT TRACE ! 20276: # ! 20277: ktrx1: movl r10,-(sp) # stack vrblk ptr for kwnam ! 20278: movl r6,-(sp) # stack offset for kwnam ! 20279: jsb prtsn # print statement number ! 20280: movl $ch$am,r6 # load ampersand ! 20281: jsb prtch # print ampersand ! 20282: jsb prtnm # print keyword name ! 20283: movl $tmbeb,r9 # point to blank-equal-blank ! 20284: jsb prtst # print blank-equal-blank ! 20285: jsb kwnam # get keyword pseudo-variable name ! 20286: movl r9,dnamp # reset ptr to delete kvblk ! 20287: jsb acess # get keyword value ! 20288: .long invalid$ # failure is impossible ! 20289: jsb prtvl # print keyword value ! 20290: jsb prtnl # terminate print line ! 20291: # ! 20292: # HERE TO EXIT AFTER COMPLETING TRACE ! 20293: # ! 20294: ktrx2: movl (sp)+,r9 # restore entry xr ! 20295: # ! 20296: # MERGE HERE TO EXIT IF NO TRACE REQUIRED ! 20297: # ! 20298: ktrx3: rsb # return to ktrex caller ! 20299: #enp # end procedure ktrex ! 20300: #page ! 20301: # ! 20302: # KWNAM -- GET PSEUDO-VARIABLE NAME FOR KEYWORD ! 20303: # ! 20304: # 1(XS) NAME BASE FOR VRBLK ! 20305: # 0(XS) OFFSET (SHOULD BE *VRVAL) ! 20306: # JSR KWNAM CALL TO GET PSEUDO-VARIABLE NAME ! 20307: # (XS) POPPED TWICE ! 20308: # (XL,WA) RESULTING PSEUDO-VARIABLE NAME ! 20309: # (XR,WA,WB) DESTROYED ! 20310: # ! 20311: .data 1 ! 20312: kwnam_s: .long 0 ! 20313: .text 0 ! 20314: kwnam: movl (sp)+,kwnam_s # entry point ! 20315: addl2 $4,sp # ignore name offset ! 20316: movl (sp)+,r9 # load name base ! 20317: cmpl r9,state # jump if not natural variable name ! 20318: bgequ kwnm1 ! 20319: tstl 4*vrlen(r9) # error if not system variable ! 20320: bnequ kwnm1 ! 20321: movl 4*vrsvp(r9),r9 # else point to svblk ! 20322: movl 4*svbit(r9),r6 # load bit mask ! 20323: mcoml btknm,r11 # and with keyword bit ! 20324: bicl2 r11,r6 ! 20325: tstl r6 # error if no keyword association ! 20326: beqlu kwnm1 ! 20327: movl 4*svlen(r9),r6 # else load name length in characters ! 20328: movab 3+(4*svchs)(r6),r6 # compute offset to field we want ! 20329: bicl2 $3,r6 ! 20330: addl2 r6,r9 # point to svknm field ! 20331: movl (r9),r7 # load svknm value ! 20332: movl $4*kvsi$,r6 # set size of kvblk ! 20333: jsb alloc # allocate kvblk ! 20334: movl $b$kvt,(r9) # store type word ! 20335: movl r7,4*kvnum(r9) # store keyword number ! 20336: movl $trbkv,4*kvvar(r9) # set dummy trblk pointer ! 20337: movl r9,r10 # copy kvblk pointer ! 20338: movl $4*kvvar,r6 # set proper offset ! 20339: jmp *kwnam_s # return to kvnam caller ! 20340: # ! 20341: # HERE IF NOT KEYWORD NAME ! 20342: # ! 20343: kwnm1: jmp er_251 # keyword operand is not name of defined keyword ! 20344: #enp # end procedure kwnam ! 20345: #page ! 20346: # ! 20347: # LCOMP-- COMPARE TWO STRINGS LEXICALLY ! 20348: # ! 20349: # 1(XS) FIRST ARGUMENT ! 20350: # 0(XS) SECOND ARGUMENT ! 20351: # JSR LCOMP CALL TO COMPARE ARUMENTS ! 20352: # PPM LOC TRANSFER LOC FOR ARG1 NOT STRING ! 20353: # PPM LOC TRANSFER LOC FOR ARG2 NOT STRING ! 20354: # PPM LOC TRANSFER LOC IF ARG1 LLT ARG2 ! 20355: # PPM LOC TRANSFER LOC IF ARG1 LEQ ARG2 ! 20356: # PPM LOC TRANSFER LOC IF ARG1 LGT ARG2 ! 20357: # (THE NORMAL RETURN IS NEVER TAKEN) ! 20358: # (XS) POPPED TWICE ! 20359: # (XR,XL) DESTROYED ! 20360: # (WA,WB,WC,RA) DESTROYED ! 20361: # ! 20362: .data 1 ! 20363: lcomp_s: .long 0 ! 20364: .text 0 ! 20365: lcomp: movl (sp)+,lcomp_s # entry point ! 20366: jsb gtstg # convert second arg to string ! 20367: .long lcmp6 # jump if second arg not string ! 20368: movl r9,r10 # else save pointer ! 20369: movl r6,r7 # and length ! 20370: jsb gtstg # convert first argument to string ! 20371: .long lcmp5 # jump if not string ! 20372: movl r6,r8 # save arg 1 length ! 20373: movab cfp$f(r9),r9 # point to chars of arg 1 ! 20374: movab cfp$f(r10),r10 # point to chars of arg 2 ! 20375: cmpl r6,r7 # jump if arg 1 length is smaller ! 20376: blequ lcmp1 ! 20377: movl r7,r6 # else set arg 2 length as smaller ! 20378: # ! 20379: # HERE WITH SMALLER LENGTH IN (WA) ! 20380: # ! 20381: lcmp1: jsb sbcmc # compare strings, jump if unequal ! 20382: .long lcmp4 ! 20383: .long lcmp3 ! 20384: cmpl r7,r8 # if equal, jump if lengths unequal ! 20385: bnequ lcmp2 ! 20386: addl3 $4*3,lcomp_s,r11 # else identical strings, leq exit ! 20387: jmp *(r11)+ ! 20388: #page ! 20389: # ! 20390: # LCOMP (CONTINUED) ! 20391: # ! 20392: # HERE IF INITIAL STRINGS IDENTICAL, BUT LENGTHS UNEQUAL ! 20393: # ! 20394: lcmp2: cmpl r8,r7 # jump if arg 1 length gt arg 2 leng ! 20395: bgequ lcmp4 ! 20396: # ! 20397: # HERE IF FIRST ARG LLT SECOND ARG ! 20398: # ! 20399: lcmp3: addl3 $4*2,lcomp_s,r11 # take llt exit ! 20400: jmp *(r11)+ ! 20401: # ! 20402: # HERE IF FIRST ARG LGT SECOND ARG ! 20403: # ! 20404: lcmp4: addl3 $4*4,lcomp_s,r11 # take lgt exit ! 20405: jmp *(r11)+ ! 20406: # ! 20407: # HERE IF FIRST ARG IS NOT A STRING ! 20408: # ! 20409: lcmp5: movl lcomp_s,r11 # take bad first arg exit ! 20410: jmp *(r11)+ ! 20411: # ! 20412: # HERE FOR SECOND ARG NOT A STRING ! 20413: # ! 20414: lcmp6: addl3 $4*1,lcomp_s,r11 # take bad second arg error exit ! 20415: jmp *(r11)+ ! 20416: #enp # end procedure lcomp ! 20417: #page ! 20418: # ! 20419: # LISTR -- LIST SOURCE LINE ! 20420: # ! 20421: # LISTR IS USED TO LIST A SOURCE LINE DURING THE INITIAL ! 20422: # COMPILATION. IT IS CALLED FROM SCANE AND SCANL. ! 20423: # ! 20424: # JSR LISTR CALL TO LIST LINE ! 20425: # (XR,XL,WA,WB,WC) DESTROYED ! 20426: # ! 20427: # GLOBAL LOCATIONS USED BY LISTR ! 20428: # ! 20429: # ERLST IF LISTING ON ACCOUNT OF AN ERROR ! 20430: # ! 20431: # LSTLC COUNT LINES ON CURRENT PAGE ! 20432: # ! 20433: # LSTNP MAX NUMBER OF LINES/PAGE ! 20434: # ! 20435: # LSTPF SET NON-ZERO IF THE CURRENT SOURCE ! 20436: # LINE HAS BEEN LISTED, ELSE ZERO. ! 20437: # ! 20438: # LSTPG COMPILER LISTING PAGE NUMBER ! 20439: # ! 20440: # LSTSN SET IF STMNT NUM TO BE LISTED ! 20441: # ! 20442: # R$CIM POINTER TO CURRENT INPUT LINE. ! 20443: # ! 20444: # R$TTL TITLE FOR SOURCE LISTING ! 20445: # ! 20446: # R$STL PTR TO SUB-TITLE STRING ! 20447: # ! 20448: # ENTRY POINT ! 20449: # ! 20450: listr: #prc # entry point ! 20451: tstl cnttl # jump if -title or -stitl ! 20452: beqlu 0f ! 20453: jmp list5 ! 20454: 0: ! 20455: tstl lstpf # immediate exit if already listed ! 20456: beqlu 0f ! 20457: jmp list4 ! 20458: 0: ! 20459: cmpl lstlc,lstnp # jump if no room ! 20460: blssu 0f ! 20461: jmp list6 ! 20462: 0: ! 20463: # ! 20464: # HERE AFTER PRINTING TITLE (IF NEEDED) ! 20465: # ! 20466: list0: movl r$cim,r9 # load pointer to current image ! 20467: movab cfp$f(r9),r9 # point to characters ! 20468: movzbl (r9),r6 # load first character ! 20469: movl lstsn,r9 # load statement number ! 20470: tstl r9 # jump if no statement number ! 20471: beqlu list2 ! 20472: movl r9,r5 # else get stmnt number as integer ! 20473: cmpl stage,$stgic # skip if execute time ! 20474: bnequ list1 ! 20475: cmpl r6,$ch$as # no stmnt number list if comment ! 20476: beqlu list2 ! 20477: cmpl r6,$ch$mn # no stmnt no. if control card ! 20478: beqlu list2 ! 20479: # ! 20480: # PRINT STATEMENT NUMBER ! 20481: # ! 20482: list1: jsb prtin # else print statement number ! 20483: clrl lstsn # and clear for next time in ! 20484: #page ! 20485: # ! 20486: # LISTR (CONTINUED) ! 20487: # ! 20488: # MERGE HERE AFTER PRINTING STATEMENT NUMBER (IF REQUIRED) ! 20489: # ! 20490: list2: movl $stnpd,profs # point past statement number ! 20491: movl r$cim,r9 # load pointer to current image ! 20492: jsb prtst # print it ! 20493: incl lstlc # bump line counter ! 20494: tstl erlst # jump if error copy to int.ch. ! 20495: bnequ list3 ! 20496: jsb prtnl # terminate line ! 20497: tstl cswdb # jump if -single mode ! 20498: beqlu list3 ! 20499: jsb prtnl # else add a blank line ! 20500: incl lstlc # and bump line counter ! 20501: # ! 20502: # HERE AFTER PRINTING SOURCE IMAGE ! 20503: # ! 20504: list3: movl sp,lstpf # set flag for line printed ! 20505: # ! 20506: # MERGE HERE TO EXIT ! 20507: # ! 20508: list4: rsb # return to listr caller ! 20509: # ! 20510: # PRINT TITLE AFTER -TITLE OR -STITL CARD ! 20511: # ! 20512: list5: clrl cnttl # clear flag ! 20513: # ! 20514: # EJECT TO NEW PAGE AND LIST TITLE ! 20515: # ! 20516: list6: jsb prtps # eject ! 20517: tstl prich # skip if listing to regular printer ! 20518: beqlu list7 ! 20519: cmpl r$ttl,$nulls # terminal listing omits null title ! 20520: bnequ 0f ! 20521: jmp list0 ! 20522: 0: ! 20523: # ! 20524: # LIST TITLE ! 20525: # ! 20526: list7: jsb listt # list title ! 20527: jmp list0 # merge ! 20528: #enp # end procedure listr ! 20529: #page ! 20530: # ! 20531: # LISTT -- LIST TITLE AND SUBTITLE ! 20532: # ! 20533: # USED DURING COMPILATION TO PRINT PAGE HEADING ! 20534: # ! 20535: # JSR LISTT CALL TO LIST TITLE ! 20536: # (XR,WA) DESTROYED ! 20537: # ! 20538: listt: #prc # entry point ! 20539: movl r$ttl,r9 # point to source listing title ! 20540: jsb prtst # print title ! 20541: movl lstpo,profs # set offset ! 20542: movl $lstms,r9 # set page message ! 20543: jsb prtst # print page message ! 20544: incl lstpg # bump page number ! 20545: movl lstpg,r5 # load page number as integer ! 20546: jsb prtin # print page number ! 20547: jsb prtnl # terminate title line ! 20548: addl2 $num02,lstlc # count title line and blank line ! 20549: # ! 20550: # PRINT SUB-TITLE (IF ANY) ! 20551: # ! 20552: movl r$stl,r9 # load pointer to sub-title ! 20553: tstl r9 # jump if no sub-title ! 20554: beqlu lstt1 ! 20555: jsb prtst # else print sub-title ! 20556: jsb prtnl # terminate line ! 20557: incl lstlc # bump line count ! 20558: # ! 20559: # RETURN POINT ! 20560: # ! 20561: lstt1: jsb prtnl # print a blank line ! 20562: rsb # return to caller ! 20563: #enp # end procedure listt ! 20564: #page ! 20565: # ! 20566: # NEXTS -- ACQUIRE NEXT SOURCE IMAGE ! 20567: # ! 20568: # NEXTS IS USED TO ACQUIRE THE NEXT SOURCE IMAGE AT COMPILE ! 20569: # TIME. IT ASSUMES THAT A PRIOR CALL TO READR HAS INPUT ! 20570: # A LINE IMAGE (SEE PROCEDURE READR). BEFORE THE CURRENT ! 20571: # IMAGE IS FINALLY LOST IT MAY BE LISTED HERE. ! 20572: # ! 20573: # JSR NEXTS CALL TO ACQUIRE NEXT INPUT LINE ! 20574: # (XR,XL,WA,WB,WC) DESTROYED ! 20575: # ! 20576: # GLOBAL VALUES AFFECTED ! 20577: # ! 20578: # R$CNI ON INPUT, NEXT IMAGE. ON ! 20579: # EXIT RESET TO ZERO ! 20580: # ! 20581: # R$CIM ON EXIT, SET TO POINT TO IMAGE ! 20582: # ! 20583: # SCNIL INPUT IMAGE LENGTH ON EXIT ! 20584: # ! 20585: # SCNSE RESET TO ZERO ON EXIT ! 20586: # ! 20587: # LSTPF SET ON EXIT IF LINE IS LISTED ! 20588: # ! 20589: nexts: #prc # entry point ! 20590: tstl cswls # jump if -nolist ! 20591: beqlu nxts2 ! 20592: movl r$cim,r9 # point to image ! 20593: tstl r9 # jump if no image ! 20594: beqlu nxts2 ! 20595: movab cfp$f(r9),r9 # get char ptr ! 20596: movzbl (r9),r6 # get first char ! 20597: cmpl r6,$ch$mn # jump if not ctrl card ! 20598: bnequ nxts1 ! 20599: tstl cswpr # jump if -noprint ! 20600: beqlu nxts2 ! 20601: # ! 20602: # HERE TO CALL LISTER ! 20603: # ! 20604: nxts1: jsb listr # list line ! 20605: # ! 20606: # HERE AFTER POSSIBLE LISTING ! 20607: # ! 20608: nxts2: movl r$cni,r9 # point to next image ! 20609: movl r9,r$cim # set as next image ! 20610: clrl r$cni # clear next image pointer ! 20611: movl 4*sclen(r9),r6 # get input image length ! 20612: movl cswin,r7 # get max allowable length ! 20613: cmpl r6,r7 # skip if not too long ! 20614: blequ nxts3 ! 20615: movl r7,r6 # else truncate ! 20616: # ! 20617: # HERE WITH LENGTH IN (WA) ! 20618: # ! 20619: nxts3: movl r6,scnil # use as record length ! 20620: clrl scnse # reset scnse ! 20621: clrl lstpf # set line not listed yet ! 20622: rsb # return to nexts caller ! 20623: #enp # end procedure nexts ! 20624: #page ! 20625: # ! 20626: # PATIN -- PATTERN CONSTRUCTION FOR LEN,POS,RPOS,TAB,RTAB ! 20627: # ! 20628: # THESE PATTERN TYPES ALL GENERATE A SIMILAR NODE TYPE. SO ! 20629: # THE CONSTRUCTION CODE IS SHARED. SEE FUNCTIONS SECTION ! 20630: # FOR ACTUAL ENTRY POINTS FOR THESE FIVE FUNCTIONS. ! 20631: # ! 20632: # (WA) PCODE FOR EXPRESSION ARG CASE ! 20633: # (WB) PCODE FOR INTEGER ARG CASE ! 20634: # JSR PATIN CALL TO BUILD PATTERN NODE ! 20635: # PPM LOC TRANSFER LOC FOR NOT INTEGER OR EXP ! 20636: # PPM LOC TRANSFER LOC FOR INT OUT OF RANGE ! 20637: # (XR) POINTER TO CONSTRUCTED NODE ! 20638: # (XL,WA,WB,WC,IA) DESTROYED ! 20639: # ! 20640: .data 1 ! 20641: patin_s: .long 0 ! 20642: .text 0 ! 20643: patin: movl (sp)+,patin_s # entry point ! 20644: movl r6,r10 # preserve expression arg pcode ! 20645: jsb gtsmi # try to convert arg as small integer ! 20646: .long ptin2 # jump if not integer ! 20647: .long ptin3 # jump if out of range ! 20648: # ! 20649: # COMMON SUCCESSFUL EXIT POINT ! 20650: # ! 20651: ptin1: jsb pbild # build pattern node ! 20652: addl3 $4*2,patin_s,r11 # return to caller ! 20653: jmp (r11) ! 20654: # ! 20655: # HERE IF ARGUMENT IS NOT AN INTEGER ! 20656: # ! 20657: ptin2: movl r10,r7 # copy expr arg case pcode ! 20658: cmpl (r9),$b$e$$ # all ok if expression arg ! 20659: blequ ptin1 ! 20660: movl patin_s,r11 # else take error exit for wrong type ! 20661: jmp *(r11)+ ! 20662: # ! 20663: # HERE FOR ERROR OF OUT OF RANGE INTEGER ARGUMENT ! 20664: # ! 20665: ptin3: addl3 $4*1,patin_s,r11 # take out-of-range error exit ! 20666: jmp *(r11)+ ! 20667: #enp # end procedure patin ! 20668: #page ! 20669: # ! 20670: # PATST -- PATTERN CONSTRUCTION FOR ANY,NOTANY, ! 20671: # BREAK,SPAN AND BREAKX PATTERN FUNCTIONS. ! 20672: # ! 20673: # THESE PATTERN FUNCTIONS BUILD SIMILAR TYPES OF NODES AND ! 20674: # THE CONSTRUCTION CODE IS SHARED. SEE FUNCTIONS SECTION ! 20675: # FOR ACTUAL ENTRY POINTS FOR THESE FIVE PATTERN FUNCTIONS. ! 20676: # ! 20677: # 0(XS) STRING ARGUMENT ! 20678: # (WB) PCODE FOR ONE CHAR ARGUMENT ! 20679: # (XL) PCODE FOR MULTI-CHAR ARGUMENT ! 20680: # (WC) PCODE FOR EXPRESSION ARGUMENT ! 20681: # JSR PATST CALL TO BUILD NODE ! 20682: # PPM LOC TRANSFER LOC IF NOT STRING OR EXPR ! 20683: # (XS) POPPED PAST STRING ARGUMENT ! 20684: # (XR) POINTER TO CONSTRUCTED NODE ! 20685: # (XL) DESTROYED ! 20686: # (WA,WB,WC,RA) DESTROYED ! 20687: # ! 20688: # NOTE THAT THERE IS A SPECIAL CALL TO PATST IN THE EVALS ! 20689: # PROCEDURE WITH A SLIGHTLY DIFFERENT FORM. SEE EVALS ! 20690: # FOR DETAILS OF THE FORM OF THIS CALL. ! 20691: # ! 20692: .data 1 ! 20693: patst_s: .long 0 ! 20694: .text 0 ! 20695: patst: movl (sp)+,patst_s # entry point ! 20696: jsb gtstg # convert argument as string ! 20697: .long pats7 # jump if not string ! 20698: cmpl r6,$num01 # jump if not one char string ! 20699: bnequ pats2 ! 20700: # ! 20701: # HERE FOR ONE CHAR STRING CASE ! 20702: # ! 20703: tstl r7 # treat as multi-char if evals call ! 20704: beqlu pats2 ! 20705: movab cfp$f(r9),r9 # point to character ! 20706: movzbl (r9),r9 # load character ! 20707: # ! 20708: # COMMON EXIT POINT AFTER SUCCESSFUL CONSTRUCTION ! 20709: # ! 20710: pats1: jsb pbild # call routine to build node ! 20711: addl3 $4*1,patst_s,r11 # return to patst caller ! 20712: jmp (r11) ! 20713: #page ! 20714: # ! 20715: # PATST (CONTINUED) ! 20716: # ! 20717: # HERE FOR MULTI-CHARACTER STRING CASE ! 20718: # ! 20719: pats2: movl r10,-(sp) # save multi-char pcode ! 20720: movl r9,-(sp) # save string pointer ! 20721: movl ctmsk,r8 # load current mask bit ! 20722: ashl $1,r8,r8 # shift to next position ! 20723: tstl r8 # skip if position left in this tbl ! 20724: bnequ pats4 ! 20725: # ! 20726: # HERE WE MUST ALLOCATE A NEW CHARACTER TABLE ! 20727: # ! 20728: movl $4*ctsi$,r6 # set size of ctblk ! 20729: jsb alloc # allocate ctblk ! 20730: movl r9,r$ctp # store ptr to new ctblk ! 20731: movl $b$ctt,(r9)+ # store type code, bump ptr ! 20732: movl $cfp$a,r7 # set number of words to clear ! 20733: movl bits0,r8 # load all zero bits ! 20734: # ! 20735: # LOOP TO CLEAR ALL BITS IN TABLE TO ZEROS ! 20736: # ! 20737: pats3: movl r8,(r9)+ # move word of zero bits ! 20738: sobgtr r7,pats3 # loop till all cleared ! 20739: movl bits1,r8 # set initial bit position ! 20740: # ! 20741: # MERGE HERE WITH BIT POSITION AVAILABLE ! 20742: # ! 20743: pats4: movl r8,ctmsk # save parm2 (new bit position) ! 20744: movl (sp)+,r10 # restore pointer to argument string ! 20745: movl 4*sclen(r10),r7 # load string length ! 20746: tstl r7 # jump if null string case ! 20747: beqlu pats6 ! 20748: # else set loop counter ! 20749: movab cfp$f(r10),r10 # point to characters in argument ! 20750: #page ! 20751: # ! 20752: # PATST (CONTINUED) ! 20753: # ! 20754: # LOOP TO SET BITS IN COLUMN OF TABLE ! 20755: # ! 20756: pats5: movzbl (r10)+,r6 # load next character ! 20757: moval 0[r6],r6 # convert to byte offset ! 20758: movl r$ctp,r9 # point to ctblk ! 20759: addl2 r6,r9 # point to ctblk entry ! 20760: movl r8,r6 # copy bit mask ! 20761: bisl2 4*ctchs(r9),r6 # or in bits already set ! 20762: movl r6,4*ctchs(r9) # store resulting bit string ! 20763: sobgtr r7,pats5 # loop till all bits set ! 20764: # ! 20765: # COMPLETE PROCESSING FOR MUTI-CHAR STRING CASE ! 20766: # ! 20767: pats6: movl r$ctp,r9 # load ctblk ptr as parm1 for pbild ! 20768: clrl r10 # clear garbage ptr in xl ! 20769: movl (sp)+,r7 # load pcode for multi-char str case ! 20770: jmp pats1 # back to exit (wc=bitstring=parm2) ! 20771: # ! 20772: # HERE IF ARGUMENT IS NOT A STRING ! 20773: # ! 20774: # NOTE THAT THE CALL FROM EVALS CANNOT PASS AN EXPRESSION ! 20775: # SINCE EVALP ALWAYS REEVALUATES EXPRESSIONS. ! 20776: # ! 20777: pats7: movl r8,r7 # set pcode for expression argument ! 20778: cmpl (r9),$b$e$$ # jump to exit if expression arg ! 20779: bgtru 0f ! 20780: jmp pats1 ! 20781: 0: ! 20782: movl patst_s,r11 # else take wrong type error exit ! 20783: jmp *(r11)+ ! 20784: #enp # end procedure patst ! 20785: #page ! 20786: # ! 20787: # PBILD -- BUILD PATTERN NODE ! 20788: # ! 20789: # (XR) PARM1 (ONLY IF REQUIRED) ! 20790: # (WB) PCODE FOR NODE ! 20791: # (WC) PARM2 (ONLY IF REQUIRED) ! 20792: # JSR PBILD CALL TO BUILD NODE ! 20793: # (XR) POINTER TO CONSTRUCTED NODE ! 20794: # (WA) DESTROYED ! 20795: # ! 20796: pbild: #prc # entry point ! 20797: movl r9,-(sp) # stack possible parm1 ! 20798: movl r7,r9 # copy pcode ! 20799: movzwl -2(r9),r9 # load entry point id (bl$px) ! 20800: cmpl r9,$bl$p1 # jump if one parameter ! 20801: beqlu pbld1 ! 20802: cmpl r9,$bl$p0 # jump if no parameters ! 20803: beqlu pbld3 ! 20804: # ! 20805: # HERE FOR TWO PARAMETER CASE ! 20806: # ! 20807: movl $4*pcsi$,r6 # set size of p2blk ! 20808: jsb alloc # allocate block ! 20809: movl r8,4*parm2(r9) # store second parameter ! 20810: jmp pbld2 # merge with one parm case ! 20811: # ! 20812: # HERE FOR ONE PARAMETER CASE ! 20813: # ! 20814: pbld1: movl $4*pbsi$,r6 # set size of p1blk ! 20815: jsb alloc # allocate node ! 20816: # ! 20817: # MERGE HERE FROM TWO PARM CASE ! 20818: # ! 20819: pbld2: movl (sp),4*parm1(r9)# store first parameter ! 20820: jmp pbld4 # merge with no parameter case ! 20821: # ! 20822: # HERE FOR CASE OF NO PARAMETERS ! 20823: # ! 20824: pbld3: movl $4*pasi$,r6 # set size of p0blk ! 20825: jsb alloc # allocate node ! 20826: # ! 20827: # MERGE HERE FROM OTHER CASES ! 20828: # ! 20829: pbld4: movl r7,(r9) # store pcode ! 20830: addl2 $4,sp # pop first parameter ! 20831: movl $ndnth,4*pthen(r9) # set nothen successor pointer ! 20832: rsb # return to pbild caller ! 20833: #enp # end procedure pbild ! 20834: #page ! 20835: # ! 20836: # PCONC -- CONCATENATE TWO PATTERNS ! 20837: # ! 20838: # (XL) PTR TO RIGHT PATTERN ! 20839: # (XR) PTR TO LEFT PATTERN ! 20840: # JSR PCONC CALL TO CONCATENATE PATTERNS ! 20841: # (XR) PTR TO CONCATENATED PATTERN ! 20842: # (XL,WA,WB,WC) DESTROYED ! 20843: # ! 20844: # ! 20845: # TO CONCATENATE TWO PATTERNS, ALL SUCCESSORS IN THE LEFT ! 20846: # PATTERN WHICH POINT TO THE NOTHEN NODE MUST BE CHANGED TO ! 20847: # POINT TO THE RIGHT PATTERN. HOWEVER, THIS MODIFICATION ! 20848: # MUST BE PERFORMED ON A COPY OF THE LEFT ARGUMENT RATHER ! 20849: # THAN THE LEFT ARGUMENT ITSELF, SINCE THE LEFT ARGUMENT ! 20850: # MAY BE POINTED TO BY SOME OTHER VARIABLE VALUE. ! 20851: # ! 20852: # ACCORDINGLY, IT IS NECESSARY TO COPY THE LEFT ARGUMENT. ! 20853: # THIS IS NOT A TRIVIAL PROCESS SINCE WE MUST AVOID COPYING ! 20854: # NODES MORE THAN ONCE AND THE PATTERN IS A GRAPH STRUCTURE ! 20855: # THE FOLLOWING ALGORITHM IS EMPLOYED. ! 20856: # ! 20857: # THE STACK IS USED TO STORE A LIST OF NODES WHICH ! 20858: # HAVE ALREADY BEEN COPIED. THE FORMAT OF THE ENTRIES ON ! 20859: # THIS LIST CONSISTS OF A TWO WORD BLOCK. THE FIRST WORD ! 20860: # IS THE OLD ADDRESS AND THE SECOND WORD IS THE ADDRESS ! 20861: # OF THE COPY. THIS LIST IS SEARCHED BY THE PCOPY ! 20862: # ROUTINE TO AVOID MAKING DUPLICATE COPIES. A TRICK IS ! 20863: # USED TO ACCOMPLISH THE CONCATENATION AT THE SAME TIME. ! 20864: # A SPECIAL ENTRY IS MADE TO START WITH ON THE STACK. THIS ! 20865: # ENTRY RECORDS THAT THE NOTHEN NODE HAS BEEN COPIED ! 20866: # ALREADY AND THE ADDRESS OF ITS COPY IS THE RIGHT PATTERN. ! 20867: # THIS AUTOMATICALLY PERFORMS THE CORRECT REPLACEMENTS. ! 20868: # ! 20869: pconc: #prc # entry point ! 20870: clrl -(sp) # make room for one entry at bottom ! 20871: movl sp,r8 # store pointer to start of list ! 20872: movl $ndnth,-(sp) # stack nothen node as old node ! 20873: movl r10,-(sp) # store right arg as copy of nothen ! 20874: movl sp,r10 # initialize pointer to stack entries ! 20875: jsb pcopy # copy first node of left arg ! 20876: movl r6,4*2(r10) # store as result under list ! 20877: #page ! 20878: # ! 20879: # PCONC (CONTINUED) ! 20880: # ! 20881: # THE FOLLOWING LOOP SCANS ENTRIES IN THE LIST AND MAKES ! 20882: # SURE THAT THEIR SUCCESSORS HAVE BEEN COPIED. ! 20883: # ! 20884: pcnc1: cmpl r10,sp # jump if all entries processed ! 20885: beqlu pcnc2 ! 20886: movl -(r10),r9 # else load next old address ! 20887: movl 4*pthen(r9),r9 # load pointer to successor ! 20888: jsb pcopy # copy successor node ! 20889: movl -(r10),r9 # load pointer to new node (copy) ! 20890: movl r6,4*pthen(r9) # store ptr to new successor ! 20891: # ! 20892: # NOW CHECK FOR SPECIAL CASE OF ALTERNATION NODE WHERE ! 20893: # PARM1 POINTS TO A NODE AND MUST BE COPIED LIKE PTHEN. ! 20894: # ! 20895: cmpl (r9),$p$alt # loop back if not ! 20896: bnequ pcnc1 ! 20897: movl 4*parm1(r9),r9 # else load pointer to alternative ! 20898: jsb pcopy # copy it ! 20899: movl (r10),r9 # restore ptr to new node ! 20900: movl r6,4*parm1(r9) # store ptr to copied alternative ! 20901: jmp pcnc1 # loop back for next entry ! 20902: # ! 20903: # HERE AT END OF COPY PROCESS ! 20904: # ! 20905: pcnc2: movl r8,sp # restore stack pointer ! 20906: movl (sp)+,r9 # load pointer to copy ! 20907: rsb # return to pconc caller ! 20908: #enp # end procedure pconc ! 20909: #page ! 20910: # ! 20911: # PCOPY -- COPY A PATTERN NODE ! 20912: # ! 20913: # PCOPY IS CALLED FROM THE PCONC PROCEDURE TO COPY A SINGLE ! 20914: # PATTERN NODE. THE COPY IS ONLY CARRIED OUT IF THE NODE ! 20915: # HAS NOT BEEN COPIED ALREADY. ! 20916: # ! 20917: # (XR) POINTER TO NODE TO BE COPIED ! 20918: # (XT) PTR TO CURRENT LOC IN COPY LIST ! 20919: # (WC) POINTER TO LIST OF COPIED NODES ! 20920: # JSR PCOPY CALL TO COPY A NODE ! 20921: # (WA) POINTER TO COPY ! 20922: # (WB,XR) DESTROYED ! 20923: # ! 20924: .data 1 ! 20925: pcopy_s: .long 0 ! 20926: .text 0 ! 20927: pcopy: movl (sp)+,pcopy_s # entry point ! 20928: movl r10,r7 # save xt ! 20929: movl r8,r10 # point to start of list ! 20930: # ! 20931: # LOOP TO SEARCH LIST OF NODES COPIED ALREADY ! 20932: # ! 20933: pcop1: subl2 $4,r10 # point to next entry on list ! 20934: cmpl r9,(r10) # jump if match ! 20935: beqlu pcop2 ! 20936: subl2 $4,r10 # else skip over copied address ! 20937: cmpl r10,sp # loop back if more to test ! 20938: bnequ pcop1 ! 20939: # ! 20940: # HERE IF NOT IN LIST, PERFORM COPY ! 20941: # ! 20942: movl (r9),r6 # load first word of block ! 20943: jsb blkln # get length of block ! 20944: movl r9,r10 # save pointer to old node ! 20945: jsb alloc # allocate space for copy ! 20946: movl r10,-(sp) # store old address on list ! 20947: movl r9,-(sp) # store new address on list ! 20948: jsb sbchk # check for stack overflow ! 20949: jsb sbmvw # move words from old block to copy ! 20950: movl (sp),r6 # load pointer to copy ! 20951: jmp pcop3 # jump to exit ! 20952: # ! 20953: # HERE IF WE FIND ENTRY IN LIST ! 20954: # ! 20955: pcop2: movl -(r10),r6 # load address of copy from list ! 20956: # ! 20957: # COMMON EXIT POINT ! 20958: # ! 20959: pcop3: movl r7,r10 # restore xt ! 20960: jmp *pcopy_s # return to pcopy caller ! 20961: #enp # end procedure pcopy ! 20962: #page ! 20963: # ! 20964: # PRFLR -- PRINT PROFILE ! 20965: # PRFLR IS CALLED TO PRINT THE CONTENTS OF THE PROFILE ! 20966: # TABLE IN A FAIRLY READABLE TABULAR FORMAT. ! 20967: # ! 20968: # JSR PRFLR CALL TO PRINT PROFILE ! 20969: # (WA,IA) DESTROYED ! 20970: # ! 20971: prflr: #prc ! 20972: tstl pfdmp # no printing if no profiling done ! 20973: bnequ 0f ! 20974: jmp prfl4 ! 20975: 0: ! 20976: movl r9,-(sp) # preserve entry xr ! 20977: movl r7,pfsvw # and also wb ! 20978: jsb prtpg # eject ! 20979: movl $pfms1,r9 # load msg /program profile/ ! 20980: jsb prtst # and print it ! 20981: jsb prtnl # followed by newline ! 20982: jsb prtnl # and another ! 20983: movl $pfms2,r9 # point to first hdr ! 20984: jsb prtst # print it ! 20985: jsb prtnl # new line ! 20986: movl $pfms3,r9 # second hdr ! 20987: jsb prtst # print it ! 20988: jsb prtnl # new line ! 20989: jsb prtnl # and another blank line ! 20990: clrl r7 # initial stmt count ! 20991: movl pftbl,r9 # point to table origin ! 20992: addl2 $4*num02,r9 # bias past xnblk header (sgd07) ! 20993: # ! 20994: # LOOP HERE TO PRINT SUCCESSIVE ENTRIES ! 20995: # ! 20996: prfl1: incl r7 # bump stmt nr ! 20997: movl (r9),r5 # load nr of executions ! 20998: tstl r5 # no printing if zero ! 20999: beql prfl3 ! 21000: movl $pfpd1,profs # point where to print ! 21001: jsb prtin # and print it ! 21002: clrl profs # back to start of line ! 21003: movl r7,r5 # load stmt nr ! 21004: jsb prtin # print it there ! 21005: movl $pfpd2,profs # and pad past count ! 21006: movl 4*cfp$i(r9),r5 # load total exec time ! 21007: jsb prtin # print that too ! 21008: movl 4*cfp$i(r9),r5 # reload time ! 21009: mull2 intth,r5 # convert to microsec ! 21010: bvs prfl2 ! 21011: divl2 (r9),r5 # divide by executions ! 21012: movl $pfpd3,profs # pad last print ! 21013: jsb prtin # and print mcsec/execn ! 21014: # ! 21015: # MERGE AFTER PRINTING TIME ! 21016: # ! 21017: prfl2: jsb prtnl # thats another line ! 21018: # ! 21019: # HERE TO GO TO NEXT ENTRY ! 21020: # ! 21021: prfl3: addl2 $4*pf$i2,r9 # bump index ptr (sgd07) ! 21022: cmpl r7,pfnte # loop if more stmts ! 21023: blssu prfl1 ! 21024: movl (sp)+,r9 # restore callers xr ! 21025: movl pfsvw,r7 # and wb too ! 21026: # ! 21027: # HERE TO EXIT ! 21028: # ! 21029: prfl4: rsb # return ! 21030: #enp # end of prflr ! 21031: #page ! 21032: # ! 21033: # PRFLU -- UPDATE AN ENTRY IN THE PROFILE TABLE ! 21034: # ! 21035: # ON ENTRY, KVSTN CONTAINS NR OF STMT TO PROFILE ! 21036: # ! 21037: # JSR PRFLU CALL TO UPDATE ENTRY ! 21038: # (IA) DESTROYED ! 21039: # ! 21040: prflu: #prc ! 21041: tstl pffnc # skip if just entered function ! 21042: beqlu 0f ! 21043: jmp pflu4 ! 21044: 0: ! 21045: movl r9,-(sp) # preserve entry xr ! 21046: movl r6,pfsvw # save wa (sgd07) ! 21047: tstl pftbl # branch if table allocated ! 21048: bnequ pflu2 ! 21049: # ! 21050: # HERE IF SPACE FOR PROFILE TABLE NOT YET ALLOCATED. ! 21051: # CALCULATE SIZE NEEDED, ALLOCATE A STATIC XNBLK, AND ! 21052: # INITIALIZE IT ALL TO ZERO. ! 21053: # THE TIME TAKEN FOR THIS WILL BE ATTRIBUTED TO THE CURRENT ! 21054: # STATEMENT (ASSIGNMENT TO KEYWD PROFILE), BUT SINCE THE ! 21055: # TIMING FOR THIS STATEMENT IS UP THE POLE ANYWAY, THIS ! 21056: # DOESNT REALLY MATTER... ! 21057: # ! 21058: subl2 $num01,pfnte # adjust for extra count (sgd07) ! 21059: movl pfi2a,r5 # convrt entry size to int ! 21060: movl r5,pfste # and store safely for later ! 21061: movl pfnte,r5 # load table length as integer ! 21062: mull2 pfste,r5 # multiply by entry size ! 21063: movl r5,r6 # get back address-style ! 21064: addl2 $num02,r6 # add on 2 word overhead ! 21065: moval 0[r6],r6 # convert the whole lot to bytes ! 21066: jsb alost # gimme the space ! 21067: movl r9,pftbl # save block pointer ! 21068: movl $b$xnt,(r9)+ # put block type and ... ! 21069: movl r6,(r9)+ # ... length into header ! 21070: movl r5,r6 # get back nr of wds in data area ! 21071: # load the counter ! 21072: # ! 21073: # LOOP HERE TO ZERO THE BLOCK DATA ! 21074: # ! 21075: pflu1: clrl (r9)+ # blank a word ! 21076: sobgtr r6,pflu1 # and alllllll the rest ! 21077: # ! 21078: # END OF ALLOCATION. MERGE BACK INTO ROUTINE ! 21079: # ! 21080: pflu2: movl kvstn,r5 # load nr of stmt just ended ! 21081: subl2 intv1,r5 # make into index offset ! 21082: mull2 pfste,r5 # make offset of table entry ! 21083: movl r5,r6 # convert to address ! 21084: moval 0[r6],r6 # get as baus ! 21085: addl2 $4*num02,r6 # offset includes table header ! 21086: movl pftbl,r9 # get table start ! 21087: cmpl r6,4*num01(r9) # if out of table, skip it ! 21088: bgequ pflu3 ! 21089: addl2 r6,r9 # else point to entry ! 21090: movl (r9),r5 # get nr of executions so far ! 21091: addl2 intv1,r5 # nudge up one ! 21092: movl r5,(r9) # and put back ! 21093: jsb systm # get time now ! 21094: movl r5,pfetm # stash ending time ! 21095: subl2 pfstm,r5 # subtract start time ! 21096: addl2 4*cfp$i(r9),r5 # add cumulative time so far ! 21097: movl r5,4*cfp$i(r9) # and put back new total ! 21098: movl pfetm,r5 # load end time of this stmt ... ! 21099: movl r5,pfstm # ... which is start time of next ! 21100: # ! 21101: # MERGE HERE TO EXIT ! 21102: # ! 21103: pflu3: movl (sp)+,r9 # restore callers xr ! 21104: movl pfsvw,r6 # restore saved reg ! 21105: rsb # and return ! 21106: # ! 21107: # HERE IF PROFILE IS SUPPRESSED BECAUSE A PROGRAM DEFINED ! 21108: # FUNCTION IS ABOUT TO BE ENTERED, AND SO THE CURRENT STMT ! 21109: # HAS NOT YET FINISHED ! 21110: # ! 21111: pflu4: clrl pffnc # reset the condition flag ! 21112: rsb # and immediate return ! 21113: #enp # end of procedure prflu ! 21114: #page ! 21115: # ! 21116: # PRPAR - PROCESS PRINT PARAMETERS ! 21117: # ! 21118: # (WC) IF NONZERO ASSOCIATE TERMINAL ONLY ! 21119: # JSR PRPAR CALL TO PROCESS PRINT PARAMETERS ! 21120: # (XL,XR,WA,WB,WC) DESTROYED ! 21121: # ! 21122: # SINCE MEMORY ALLOCATION IS UNDECIDED ON INITIAL CALL, ! 21123: # TERMINAL CANNOT BE ASSOCIATED. THE ENTRY WITH WC NON-ZERO ! 21124: # IS PROVIDED SO A LATER CALL CAN BE MADE TO COMPLETE THIS. ! 21125: # ! 21126: prpar: #prc # entry point ! 21127: tstl r8 # jump to associate terminal ! 21128: beqlu 0f ! 21129: jmp prpa7 ! 21130: 0: ! 21131: jsb syspp # get print parameters ! 21132: tstl r7 # jump if lines/page specified ! 21133: bnequ prpa1 ! 21134: movl $cfp$m,r7 # else use a large value ! 21135: ashl $-1,r7,r7 # but not too large ! 21136: # ! 21137: # STORE LINE COUNT/PAGE ! 21138: # ! 21139: prpa1: movl r7,lstnp # store number of lines/page ! 21140: movl r7,lstlc # pretend page is full initially ! 21141: clrl lstpg # clear page number ! 21142: movl prlen,r7 # get prior length if any ! 21143: tstl r7 # skip if no length ! 21144: beqlu prpa2 ! 21145: cmpl r6,r7 # skip storing if too big ! 21146: bgtru prpa3 ! 21147: # ! 21148: # STORE PRINT BUFFER LENGTH ! 21149: # ! 21150: prpa2: movl r6,prlen # store value ! 21151: # ! 21152: # PROCESS BITS OPTIONS ! 21153: # ! 21154: prpa3: movl bits3,r7 # bit 3 mask ! 21155: mcoml r8,r11 # get -nolist bit ! 21156: bicl2 r11,r7 ! 21157: tstl r7 # skip if clear ! 21158: beqlu prpa4 ! 21159: clrl cswls # set -nolist ! 21160: # ! 21161: # CHECK IF FAIL REPORTS GOTO INTERACTIVE CHANNEL ! 21162: # ! 21163: prpa4: movl bits1,r7 # bit 1 mask ! 21164: mcoml r8,r11 # get bit ! 21165: bicl2 r11,r7 ! 21166: movl r7,erich # store int. chan. error flag ! 21167: movl bits2,r7 # bit 2 mask ! 21168: mcoml r8,r11 # get bit ! 21169: bicl2 r11,r7 ! 21170: movl r7,prich # flag for std printer on int. chan. ! 21171: movl bits4,r7 # bit 4 mask ! 21172: mcoml r8,r11 # get bit ! 21173: bicl2 r11,r7 ! 21174: movl r7,cpsts # flag for compile stats suppressn. ! 21175: movl bits5,r7 # bit 5 mask ! 21176: mcoml r8,r11 # get bit ! 21177: bicl2 r11,r7 ! 21178: movl r7,exsts # flag for exec stats suppression ! 21179: #page ! 21180: # ! 21181: # PRPAR (CONTINUED) ! 21182: # ! 21183: movl bits6,r7 # bit 6 mask ! 21184: mcoml r8,r11 # get bit ! 21185: bicl2 r11,r7 ! 21186: movl r7,precl # extended/compact listing flag ! 21187: subl2 $num08,r6 # point 8 chars from line end ! 21188: tstl r7 # jump if not extended ! 21189: beqlu prpa5 ! 21190: movl r6,lstpo # store for listing page headings ! 21191: # ! 21192: # CONTINUE OPTION PROCESSING ! 21193: # ! 21194: prpa5: movl bits7,r7 # bit 7 mask ! 21195: mcoml r8,r11 # get bit 7 ! 21196: bicl2 r11,r7 ! 21197: movl r7,cswex # set -noexecute if non-zero ! 21198: movl bit10,r7 # bit 10 mask ! 21199: mcoml r8,r11 # get bit 10 ! 21200: bicl2 r11,r7 ! 21201: movl r7,headp # pretend printed to omit headers ! 21202: movl bits9,r7 # bit 9 mask ! 21203: mcoml r8,r11 # get bit 9 ! 21204: bicl2 r11,r7 ! 21205: movl r7,prsto # keep it as std listing option ! 21206: tstl r7 # skip if clear ! 21207: beqlu prpa6 ! 21208: movl prlen,r6 # get print buffer length ! 21209: subl2 $num08,r6 # point 8 chars from line end ! 21210: movl r6,lstpo # store page offset ! 21211: # ! 21212: # CHECK FOR TERMINAL ! 21213: # ! 21214: prpa6: mcoml bits8,r11 # see if terminal to be activated ! 21215: bicl2 r11,r8 ! 21216: tstl r8 # jump if terminal required ! 21217: beqlu 0f ! 21218: jmp prpa7 ! 21219: 0: ! 21220: tstl initr # jump if no terminal to detach ! 21221: beqlu prpa8 ! 21222: movl $v$ter,r10 # ptr to /terminal/ ! 21223: jsb gtnvr # get vrblk pointer ! 21224: .long invalid$ # cant fail ! 21225: movl $nulls,4*vrval(r9) # clear value of terminal ! 21226: jsb setvr # remove association ! 21227: jmp prpa8 # return ! 21228: # ! 21229: # ASSOCIATE TERMINAL ! 21230: # ! 21231: prpa7: movl sp,initr # note terminal associated ! 21232: tstl dnamb # cant if memory not organised ! 21233: beqlu prpa8 ! 21234: movl $v$ter,r10 # point to terminal string ! 21235: movl $trtou,r7 # output trace type ! 21236: jsb inout # attach output trblk to vrblk ! 21237: movl r9,-(sp) # stack trblk ptr ! 21238: movl $v$ter,r10 # point to terminal string ! 21239: movl $trtin,r7 # input trace type ! 21240: jsb inout # attach input trace blk ! 21241: movl (sp)+,4*vrval(r9)# add output trblk to chain ! 21242: # ! 21243: # RETURN POINT ! 21244: # ! 21245: prpa8: rsb # return ! 21246: #enp # end procedure prpar ! 21247: #page ! 21248: # ! 21249: # PRTCH -- PRINT A CHARACTER ! 21250: # ! 21251: # PRTCH IS USED TO PRINT A SINGLE CHARACTER ! 21252: # ! 21253: # (WA) CHARACTER TO BE PRINTED ! 21254: # JSR PRTCH CALL TO PRINT CHARACTER ! 21255: # ! 21256: prtch: #prc # entry point ! 21257: movl r9,-(sp) # save xr ! 21258: cmpl profs,prlen # jump if room in buffer ! 21259: bnequ prch1 ! 21260: jsb prtnl # else print this line ! 21261: # ! 21262: # HERE AFTER MAKING SURE WE HAVE ROOM ! 21263: # ! 21264: prch1: movl prbuf,r9 # point to print buffer ! 21265: movl profs,r11 # [get in scratch register] ! 21266: movab cfp$f(r9)[r11],r9# point to next character location ! 21267: movb r6,(r9) # store new character ! 21268: #csc r9 # complete store characters ! 21269: incl profs # bump pointer ! 21270: movl (sp)+,r9 # restore entry xr ! 21271: rsb # return to prtch caller ! 21272: #enp # end procedure prtch ! 21273: #page ! 21274: # ! 21275: # PRTIC -- PRINT TO INTERACTIVE CHANNEL ! 21276: # ! 21277: # PRTIC IS CALLED TO PRINT THE CONTENTS OF THE STANDARD ! 21278: # PRINT BUFFER TO THE INTERACTIVE CHANNEL. IT IS ONLY ! 21279: # CALLED AFTER PRTST HAS SET UP THE STRING FOR PRINTING. ! 21280: # IT DOES NOT CLEAR THE BUFFER. ! 21281: # ! 21282: # JSR PRTIC CALL FOR PRINT ! 21283: # (WA,WB) DESTROYED ! 21284: # ! 21285: prtic: #prc # entry point ! 21286: movl r9,-(sp) # save xr ! 21287: movl prbuf,r9 # point to buffer ! 21288: movl profs,r6 # no of chars ! 21289: jsb syspi # print ! 21290: .long prtc2 # fail return ! 21291: # ! 21292: # RETURN ! 21293: # ! 21294: prtc1: movl (sp)+,r9 # restore xr ! 21295: rsb # return ! 21296: # ! 21297: # ERROR OCCURED ! 21298: # ! 21299: prtc2: clrl erich # prevent looping ! 21300: jmp er_252 # error on printing to interactive channel ! 21301: jmp prtc1 # return ! 21302: #enp # procedure prtic ! 21303: #page ! 21304: # ! 21305: # PRTIS -- PRINT TO INTERACTIVE AND STANDARD PRINTER ! 21306: # ! 21307: # PRTIS PUTS A LINE FROM THE PRINT BUFFER ONTO THE ! 21308: # INTERACTIVE CHANNEL (IF ANY) AND THE STANDARD PRINTER. ! 21309: # IT ALWAYS PRINTS TO THE STANDARD PRINTER BUT DOES ! 21310: # NOT DUPLICATE LINES IF THE STANDARD PRINTER IS ! 21311: # INTERACTIVE. IT CLEARS DOWN THE PRINT BUFFER. ! 21312: # ! 21313: # JSR PRTIS CALL FOR PRINTING ! 21314: # (WA,WB) DESTROYED ! 21315: # ! 21316: prtis: #prc # entry point ! 21317: tstl prich # jump if standard printer is int.ch. ! 21318: bnequ prts1 ! 21319: tstl erich # skip if not doing int. error reps. ! 21320: beqlu prts1 ! 21321: jsb prtic # print to interactive channel ! 21322: # ! 21323: # MERGE AND EXIT ! 21324: # ! 21325: prts1: jsb prtnl # print to standard printer ! 21326: rsb # return ! 21327: #enp # end procedure prtis ! 21328: #page ! 21329: # ! 21330: # PRTIN -- PRINT AN INTEGER ! 21331: # ! 21332: # PRTIN PRINTS THE INTEGER VALUE WHICH IS IN THE INTEGER ! 21333: # ACCUMULATOR. BLOCKS BUILT IN DYNAMIC STORAGE ! 21334: # DURING THIS PROCESS ARE IMMEDIATELY DELETED. ! 21335: # ! 21336: # (IA) INTEGER VALUE TO BE PRINTED ! 21337: # JSR PRTIN CALL TO PRINT INTEGER ! 21338: # (IA,RA) DESTROYED ! 21339: # ! 21340: prtin: #prc # entry point ! 21341: movl r9,-(sp) # save xr ! 21342: jsb icbld # build integer block ! 21343: cmpl r9,dnamb # jump if icblk below dynamic ! 21344: blequ prti1 ! 21345: cmpl r9,dnamp # jump if above dynamic ! 21346: bgequ prti1 ! 21347: movl r9,dnamp # immediately delete it ! 21348: # ! 21349: # DELETE ICBLK FROM DYNAMIC STORE ! 21350: # ! 21351: prti1: movl r9,-(sp) # stack ptr for gtstg ! 21352: jsb gtstg # convert to string ! 21353: .long invalid$ # convert error is impossible ! 21354: movl r9,dnamp # reset pointer to delete scblk ! 21355: jsb prtst # print integer string ! 21356: movl (sp)+,r9 # restore entry xr ! 21357: rsb # return to prtin caller ! 21358: #enp # end procedure prtin ! 21359: #page ! 21360: # ! 21361: # PRTMI -- PRINT MESSAGE AND INTEGER ! 21362: # ! 21363: # PRTMI IS USED TO PRINT MESSAGES TOGETHER WITH AN INTEGER ! 21364: # VALUE STARTING IN COLUMN 15 (USED BY THE ROUTINES AT ! 21365: # THE END OF COMPILATION). ! 21366: # ! 21367: # JSR PRTMI CALL TO PRINT MESSAGE AND INTEGER ! 21368: # ! 21369: prtmi: #prc # entry point ! 21370: jsb prtst # print string message ! 21371: movl $prtmf,profs # set offset to col 15 ! 21372: jsb prtin # print integer ! 21373: jsb prtnl # print line ! 21374: rsb # return to prtmi caller ! 21375: #enp # end procedure prtmi ! 21376: #page ! 21377: # ! 21378: # PRTMX -- AS PRTMI WITH EXTRA COPY TO INTERACTIVE CHAN. ! 21379: # ! 21380: # JSR PRTMX CALL FOR PRINTING ! 21381: # (WA,WB) DESTROYED ! 21382: # ! 21383: prtmx: #prc # entry point ! 21384: jsb prtst # print string message ! 21385: movl $prtmf,profs # set ptr to column 15 ! 21386: jsb prtin # print integer ! 21387: jsb prtis # print line ! 21388: rsb # return ! 21389: #enp # end procedure prtmx ! 21390: #page ! 21391: # ! 21392: # PRTNL -- PRINT NEW LINE (END PRINT LINE) ! 21393: # ! 21394: # PRTNL PRINTS THE CONTENTS OF THE PRINT BUFFER, RESETS ! 21395: # THE BUFFER TO ALL BLANKS AND RESETS THE PRINT POINTER. ! 21396: # ! 21397: # JSR PRTNL CALL TO PRINT LINE ! 21398: # ! 21399: prtnl: #prc # entry point ! 21400: tstl headp # were headers printed ! 21401: bnequ prnl0 ! 21402: jsb prtps # no - print them ! 21403: # ! 21404: # CALL SYSPR ! 21405: # ! 21406: prnl0: movl r9,-(sp) # save entry xr ! 21407: movl r6,prtsa # save wa ! 21408: movl r7,prtsb # save wb ! 21409: movl prbuf,r9 # load pointer to buffer ! 21410: movl profs,r6 # load number of chars in buffer ! 21411: jsb syspr # call system print routine ! 21412: .long prnl2 # jump if failed ! 21413: movl prlnw,r6 # load length of buffer in words ! 21414: addl2 $4*schar,r9 # point to chars of buffer ! 21415: movl nullw,r7 # get word of blanks ! 21416: # ! 21417: # LOOP TO BLANK BUFFER ! 21418: # ! 21419: prnl1: movl r7,(r9)+ # store word of blanks, bump ptr ! 21420: sobgtr r6,prnl1 # loop till all blanked ! 21421: # ! 21422: # EXIT POINT ! 21423: # ! 21424: movl prtsb,r7 # restore wb ! 21425: movl prtsa,r6 # restore wa ! 21426: movl (sp)+,r9 # restore entry xr ! 21427: clrl profs # reset print buffer pointer ! 21428: rsb # return to prtnl caller ! 21429: # ! 21430: # FILE FULL OR NO OUTPUT FILE FOR LOAD MODULE ! 21431: # ! 21432: prnl2: tstl prtef # jump if not first time ! 21433: bnequ prnl3 ! 21434: movl sp,prtef # mark first occurrence ! 21435: jmp er_253 # print limit exceeded on standard output channel ! 21436: # ! 21437: # STOP AT ONCE ! 21438: # ! 21439: prnl3: movl $nini8,r7 # ending code ! 21440: movl kvstn,r6 # statement number ! 21441: jsb sysej # stop ! 21442: #enp # end procedure prtnl ! 21443: #page ! 21444: # ! 21445: # PRTNM -- PRINT VARIABLE NAME ! 21446: # ! 21447: # PRTNM IS USED TO PRINT A CHARACTER REPRESENTATION OF THE ! 21448: # NAME OF A VARIABLE (NOT A VALUE OF DATATYPE NAME) ! 21449: # NAMES OF PSEUDO-VARIABLES MAY NOT BE PASSED TO PRTNM. ! 21450: # ! 21451: # (XL) NAME BASE ! 21452: # (WA) NAME OFFSET ! 21453: # JSR PRTNM CALL TO PRINT NAME ! 21454: # (WB,WC,RA) DESTROYED ! 21455: # ! 21456: prtnm: #prc # entry point (recursive, see prtvl) ! 21457: movl r6,-(sp) # save wa (offset is collectable) ! 21458: movl r9,-(sp) # save entry xr ! 21459: movl r10,-(sp) # save name base ! 21460: cmpl r10,state # jump if not natural variable ! 21461: bgequ prn02 ! 21462: # ! 21463: # HERE FOR NATURAL VARIABLE NAME, RECOGNIZED BY THE FACT ! 21464: # THAT THE NAME BASE POINTS INTO THE STATIC AREA. ! 21465: # ! 21466: movl r10,r9 # point to vrblk ! 21467: jsb prtvn # print name of variable ! 21468: # ! 21469: # COMMON EXIT POINT ! 21470: # ! 21471: prn01: movl (sp)+,r10 # restore name base ! 21472: movl (sp)+,r9 # restore entry value of xr ! 21473: movl (sp)+,r6 # restore wa ! 21474: rsb # return to prtnm caller ! 21475: # ! 21476: # HERE FOR CASE OF NON-NATURAL VARIABLE ! 21477: # ! 21478: prn02: movl r6,r7 # copy name offset ! 21479: cmpl (r10),$b$pdt # jump if array or table ! 21480: bnequ prn03 ! 21481: # ! 21482: # FOR PROGRAM DEFINED DATATYPE, PRT FLD NAME, LEFT PAREN ! 21483: # ! 21484: movl 4*pddfp(r10),r9 # load pointer to dfblk ! 21485: addl2 r6,r9 # add name offset ! 21486: movl 4*pdfof(r9),r9 # load vrblk pointer for field ! 21487: jsb prtvn # print field name ! 21488: movl $ch$pp,r6 # load left paren ! 21489: jsb prtch # print character ! 21490: #page ! 21491: # ! 21492: # PRTNM (CONTINUED) ! 21493: # ! 21494: # NOW WE PRINT AN IDENTIFYING NAME FOR THE OBJECT IF ONE ! 21495: # CAN BE FOUND. THE FOLLOWING CODE SEARCHES FOR A NATURAL ! 21496: # VARIABLE WHICH CONTAINS THIS OBJECT AS VALUE. IF SUCH A ! 21497: # VARIABLE IS FOUND, ITS NAME IS PRINTED, ELSE THE VALUE ! 21498: # OF THE OBJECT (AS PRINTED BY PRTVL) IS USED INSTEAD. ! 21499: # ! 21500: # FIRST WE POINT TO THE PARENT TBBLK IF THIS IS THE CASE OF ! 21501: # A TABLE ELEMENT. TO DO THIS, CHASE DOWN THE TRNXT CHAIN. ! 21502: # ! 21503: prn03: cmpl (r10),$b$tet # jump if we got there (or not te) ! 21504: bnequ prn04 ! 21505: movl 4*tenxt(r10),r10# else move out on chain ! 21506: jmp prn03 # and loop back ! 21507: # ! 21508: # NOW WE ARE READY FOR THE SEARCH. TO SPEED THINGS UP IN ! 21509: # THE CASE OF CALLS FROM DUMP WHERE THE SAME NAME BASE ! 21510: # WILL OCCUR REPEATEDLY WHILE DUMPING AN ARRAY OR TABLE, ! 21511: # WE REMEMBER THE LAST VRBLK POINTER FOUND IN PRNMV. SO ! 21512: # FIRST CHECK TO SEE IF WE HAVE THIS ONE AGAIN. ! 21513: # ! 21514: prn04: movl prnmv,r9 # point to vrblk we found last time ! 21515: movl hshtb,r6 # point to hash table in case not ! 21516: jmp prn07 # jump into search for special check ! 21517: # ! 21518: # LOOP THROUGH HASH SLOTS ! 21519: # ! 21520: prn05: movl r6,r9 # copy slot pointer ! 21521: addl2 $4,r6 # bump slot pointer ! 21522: subl2 $4*vrnxt,r9 # introduce standard vrblk offset ! 21523: # ! 21524: # LOOP THROUGH VRBLKS ON ONE HASH CHAIN ! 21525: # ! 21526: prn06: movl 4*vrnxt(r9),r9 # point to next vrblk on hash chain ! 21527: # ! 21528: # MERGE HERE FIRST TIME TO CHECK BLOCK WE FOUND LAST TIME ! 21529: # ! 21530: prn07: movl r9,r8 # copy vrblk pointer ! 21531: tstl r8 # jump if chain end (or prnmv zero) ! 21532: beqlu prn09 ! 21533: #page ! 21534: # ! 21535: # PRTNM (CONTINUED) ! 21536: # ! 21537: # LOOP TO FIND VALUE (CHASE DOWN POSSIBLE TRBLK CHAIN) ! 21538: # ! 21539: prn08: movl 4*vrval(r9),r9 # load value ! 21540: cmpl (r9),$b$trt # loop if that was a trblk ! 21541: beqlu prn08 ! 21542: # ! 21543: # NOW WE HAVE THE VALUE, IS THIS THE BLOCK WE WANT ! 21544: # ! 21545: cmpl r9,r10 # jump if this matches the name base ! 21546: beqlu prn10 ! 21547: movl r8,r9 # else point back to that vrblk ! 21548: jmp prn06 # and loop back ! 21549: # ! 21550: # HERE TO MOVE TO NEXT HASH SLOT ! 21551: # ! 21552: prn09: cmpl r6,hshte # loop back if more to go ! 21553: blssu prn05 ! 21554: movl r10,r9 # else not found, copy value pointer ! 21555: jsb prtvl # print value ! 21556: jmp prn11 # and merge ahead ! 21557: # ! 21558: # HERE WHEN WE FIND A MATCHING ENTRY ! 21559: # ! 21560: prn10: movl r8,r9 # copy vrblk pointer ! 21561: movl r9,prnmv # save for next time in ! 21562: jsb prtvn # print variable name ! 21563: # ! 21564: # MERGE HERE IF NO ENTRY FOUND ! 21565: # ! 21566: prn11: movl (r10),r8 # load first word of name base ! 21567: cmpl r8,$b$pdt # jump if not program defined ! 21568: bnequ prn13 ! 21569: # ! 21570: # FOR PROGRAM DEFINED DATATYPE, ADD RIGHT PAREN AND EXIT ! 21571: # ! 21572: movl $ch$rp,r6 # load right paren, merge ! 21573: # ! 21574: # MERGE HERE TO PRINT FINAL RIGHT PAREN OR BRACKET ! 21575: # ! 21576: prn12: jsb prtch # print final character ! 21577: movl r7,r6 # restore name offset ! 21578: jmp prn01 # merge back to exit ! 21579: #page ! 21580: # ! 21581: # PRTNM (CONTINUED) ! 21582: # ! 21583: # HERE FOR ARRAY OR TABLE ! 21584: # ! 21585: prn13: movl $ch$bb,r6 # load left bracket ! 21586: jsb prtch # and print it ! 21587: movl (sp),r10 # restore block pointer ! 21588: movl (r10),r8 # load type word again ! 21589: cmpl r8,$b$tet # jump if not table ! 21590: bnequ prn15 ! 21591: # ! 21592: # HERE FOR TABLE, PRINT SUBSCRIPT VALUE ! 21593: # ! 21594: movl 4*tesub(r10),r9 # load subscript value ! 21595: movl r7,r10 # save name offset ! 21596: jsb prtvl # print subscript value ! 21597: movl r10,r7 # restore name offset ! 21598: # ! 21599: # MERGE HERE FROM ARRAY CASE TO PRINT RIGHT BRACKET ! 21600: # ! 21601: prn14: movl $ch$rb,r6 # load right bracket ! 21602: jmp prn12 # merge back to print it ! 21603: # ! 21604: # HERE FOR ARRAY OR VECTOR, TO PRINT SUBSCRIPT(S) ! 21605: # ! 21606: prn15: movl r7,r6 # copy name offset ! 21607: ashl $-2,r6,r6 # convert to words ! 21608: cmpl r8,$b$art # jump if arblk ! 21609: beqlu prn16 ! 21610: # ! 21611: # HERE FOR VECTOR ! 21612: # ! 21613: subl2 $vcvlb,r6 # adjust for standard fields ! 21614: movl r6,r5 # move to integer accum ! 21615: jsb prtin # print linear subscript ! 21616: jmp prn14 # merge back for right bracket ! 21617: #page ! 21618: # ! 21619: # PRTNM (CONTINUED) ! 21620: # ! 21621: # HERE FOR ARRAY. FIRST CALCULATE ABSOLUTE SUBSCRIPT ! 21622: # OFFSETS BY SUCCESSIVE DIVISIONS BY THE DIMENSION VALUES. ! 21623: # THIS MUST BE DONE RIGHT TO LEFT SINCE THE ELEMENTS ARE ! 21624: # STORED ROW-WISE. THE SUBSCRIPTS ARE STACKED AS INTEGERS. ! 21625: # ! 21626: prn16: movl 4*arofs(r10),r8 # load length of bounds info ! 21627: addl2 $4,r8 # adjust for arpro field ! 21628: ashl $-2,r8,r8 # convert to words ! 21629: subl2 r8,r6 # get linear zero-origin subscript ! 21630: movl r6,r5 # get integer value ! 21631: movl 4*arndm(r10),r6 # set num of dimensions as loop count ! 21632: addl2 4*arofs(r10),r10# point past bounds information ! 21633: subl2 $4*arlbd,r10 # set ok offset for proper ptr later ! 21634: # ! 21635: # LOOP TO STACK SUBSCRIPT OFFSETS ! 21636: # ! 21637: prn17: subl2 $4*ardms,r10 # point to next set of bounds ! 21638: movl r5,prnsi # save current offset ! 21639: ashq $-32,r4,r4 # get remainder on dividing by dimens ! 21640: ediv 4*ardim(r10),r4,r11,r5 ! 21641: movl r5,-(sp) # store on stack (one word) ! 21642: movl prnsi,r5 # reload argument ! 21643: divl2 4*ardim(r10),r5 # divide to get quotient ! 21644: sobgtr r6,prn17 # loop till all stacked ! 21645: clrl r9 # set offset to first set of bounds ! 21646: movl 4*arndm(r10),r7 # load count of dims to control loop ! 21647: jmp prn19 # jump into print loop ! 21648: # ! 21649: # LOOP TO PRINT SUBSCRIPTS FROM STACK ADJUSTING BY ADDING ! 21650: # THE APPROPRIATE LOW BOUND VALUE FROM THE ARBLK ! 21651: # ! 21652: prn18: movl $ch$cm,r6 # load a comma ! 21653: jsb prtch # print it ! 21654: # ! 21655: # MERGE HERE FIRST TIME IN (NO COMMA REQUIRED) ! 21656: # ! 21657: prn19: movl (sp)+,r5 # load subscript offset as integer ! 21658: addl2 r9,r10 # point to current lbd ! 21659: addl2 4*arlbd(r10),r5 # add lbd to get signed subscript ! 21660: subl2 r9,r10 # point back to start of arblk ! 21661: jsb prtin # print subscript ! 21662: addl2 $4*ardms,r9 # bump offset to next bounds ! 21663: sobgtr r7,prn18 # loop back till all printed ! 21664: jmp prn14 # merge back to print right bracket ! 21665: #enp # end procedure prtnm ! 21666: #page ! 21667: # ! 21668: # PRTNV -- PRINT NAME VALUE ! 21669: # ! 21670: # PRTNV IS USED BY THE TRACE AND DUMP ROUTINES TO PRINT ! 21671: # A LINE OF THE FORM ! 21672: # ! 21673: # NAME = VALUE ! 21674: # ! 21675: # NOTE THAT THE NAME INVOLVED CAN NEVER BE A PSEUDO-VAR ! 21676: # ! 21677: # (XL) NAME BASE ! 21678: # (WA) NAME OFFSET ! 21679: # JSR PRTNV CALL TO PRINT NAME = VALUE ! 21680: # (WB,WC,RA) DESTROYED ! 21681: # ! 21682: prtnv: #prc # entry point ! 21683: jsb prtnm # print argument name ! 21684: movl r9,-(sp) # save entry xr ! 21685: movl r6,-(sp) # save name offset (collectable) ! 21686: movl $tmbeb,r9 # point to blank equal blank ! 21687: jsb prtst # print it ! 21688: movl r10,r9 # copy name base ! 21689: addl2 r6,r9 # point to value ! 21690: movl (r9),r9 # load value pointer ! 21691: jsb prtvl # print value ! 21692: jsb prtnl # terminate line ! 21693: movl (sp)+,r6 # restore name offset ! 21694: movl (sp)+,r9 # restore entry xr ! 21695: rsb # return to caller ! 21696: #enp # end procedure prtnv ! 21697: #page ! 21698: # ! 21699: # PRTPG -- PRINT A PAGE THROW ! 21700: # ! 21701: # PRINTS A PAGE THROW OR A FEW BLANK LINES ON THE STANDARD ! 21702: # LISTING CHANNEL DEPENDING ON THE LISTING OPTIONS CHOSEN. ! 21703: # ! 21704: # JSR PRTPG CALL FOR PAGE EJECT ! 21705: # ! 21706: prtpg: #prc # entry point ! 21707: cmpl stage,$stgxt # jump if execution time ! 21708: beqlu prp01 ! 21709: tstl lstlc # return if top of page already ! 21710: bnequ 0f ! 21711: jmp prp06 ! 21712: 0: ! 21713: clrl lstlc # clear line count ! 21714: # ! 21715: # CHECK TYPE OF LISTING ! 21716: # ! 21717: prp01: movl r9,-(sp) # preserve xr ! 21718: tstl prstd # eject if flag set ! 21719: bnequ prp02 ! 21720: tstl prich # jump if interactive listing channel ! 21721: bnequ prp03 ! 21722: tstl precl # jump if compact listing ! 21723: beqlu prp03 ! 21724: # ! 21725: # PERFORM AN EJECT ! 21726: # ! 21727: prp02: jsb sysep # eject ! 21728: jmp prp04 # merge ! 21729: # ! 21730: # COMPACT OR INTERACTIVE CHANNEL LISTING. CANT PRINT ! 21731: # BLANKS UNTIL CHECK MADE FOR HEADERS PRINTED AND FLAG SET. ! 21732: # ! 21733: # ! 21734: prp03: movl headp,r9 # remember headp ! 21735: movl sp,headp # set to avoid repeated prtpg calls ! 21736: jsb prtnl # print blank line ! 21737: jsb prtnl # print blank line ! 21738: jsb prtnl # print blank line ! 21739: movl $num03,lstlc # count blank lines ! 21740: movl r9,headp # restore header flag ! 21741: #page ! 21742: # ! 21743: # PRPTG (CONTINUED) ! 21744: # ! 21745: # PRINT THE HEADING ! 21746: # ! 21747: prp04: tstl headp # jump if header listed ! 21748: bnequ prp05 ! 21749: movl sp,headp # mark headers printed ! 21750: movl r10,-(sp) # keep xl ! 21751: movl $headr,r9 # point to listing header ! 21752: jsb prtst # place it ! 21753: jsb sysid # get system identification ! 21754: jsb prtst # append extra chars ! 21755: jsb prtnl # print it ! 21756: movl r10,r9 # extra header line ! 21757: jsb prtst # place it ! 21758: jsb prtnl # print it ! 21759: jsb prtnl # print a blank ! 21760: jsb prtnl # and another ! 21761: addl2 $num04,lstlc # four header lines printed ! 21762: movl (sp)+,r10 # restore xl ! 21763: # ! 21764: # MERGE IF HEADER NOT PRINTED ! 21765: # ! 21766: prp05: movl (sp)+,r9 # restore xr ! 21767: # ! 21768: # RETURN ! 21769: # ! 21770: prp06: rsb # return ! 21771: #enp # end procedure prtpg ! 21772: #page ! 21773: # ! 21774: # PRTPS - PRINT PAGE WITH TEST FOR STANDARD LISTING OPTION ! 21775: # ! 21776: # IF THE STANDARD LISTING OPTION IS SELECTED, INSIST THAT ! 21777: # AN EJECT BE DONE ! 21778: # ! 21779: # JSR PRTPS CALL FOR EJECT ! 21780: # ! 21781: prtps: #prc # entry point ! 21782: movl prsto,prstd # copy option flag ! 21783: jsb prtpg # print page ! 21784: clrl prstd # clear flag ! 21785: rsb # return ! 21786: #enp # end procedure prtps ! 21787: #page ! 21788: # ! 21789: # PRTSN -- PRINT STATEMENT NUMBER ! 21790: # ! 21791: # PRTSN IS USED TO INITIATE A PRINT TRACE LINE BY PRINTING ! 21792: # ASTERISKS AND THE CURRENT STATEMENT NUMBER. THE ACTUAL ! 21793: # FORMAT OF THE OUTPUT GENERATED IS. ! 21794: # ! 21795: # ***NNNNN**** III.....IIII ! 21796: # ! 21797: # NNNNN IS THE STATEMENT NUMBER WITH LEADING ZEROS REPLACED ! 21798: # BY ASTERISKS (E.G. *******9****) ! 21799: # ! 21800: # III...III REPRESENTS A VARIABLE LENGTH OUTPUT CONSISTING ! 21801: # OF A NUMBER OF LETTER I CHARACTERS EQUAL TO FNCLEVEL. ! 21802: # ! 21803: # JSR PRTSN CALL TO PRINT STATEMENT NUMBER ! 21804: # (WC) DESTROYED ! 21805: # ! 21806: prtsn: #prc # entry point ! 21807: movl r9,-(sp) # save entry xr ! 21808: movl r6,prsna # save entry wa ! 21809: movl $tmasb,r9 # point to asterisks ! 21810: jsb prtst # print asterisks ! 21811: movl $num04,profs # point into middle of asterisks ! 21812: movl kvstn,r5 # load statement number as integer ! 21813: jsb prtin # print integer statement number ! 21814: movl $prsnf,profs # point past asterisks plus blank ! 21815: movl kvfnc,r9 # get fnclevel ! 21816: movl $ch$li,r6 # set letter i ! 21817: # ! 21818: # LOOP TO GENERATE LETTER I FNCLEVEL TIMES ! 21819: # ! 21820: prsn1: tstl r9 # jump if all set ! 21821: beqlu prsn2 ! 21822: jsb prtch # else print an i ! 21823: decl r9 # decrement counter ! 21824: jmp prsn1 # loop back ! 21825: # ! 21826: # MERRE WITH ALL LETTER I CHARACTERS GENERATED ! 21827: # ! 21828: prsn2: movl $ch$bl,r6 # get blank ! 21829: jsb prtch # print blank ! 21830: movl prsna,r6 # restore entry wa ! 21831: movl (sp)+,r9 # restore entry xr ! 21832: rsb # return to prtsn caller ! 21833: #enp # end procedure prtsn ! 21834: #page ! 21835: # ! 21836: # PRTST -- PRINT STRING ! 21837: # ! 21838: # PRTST PLACES A STRING OF CHARACTERS IN THE PRINT BUFFER ! 21839: # ! 21840: # SEE PRTNL FOR GLOBAL LOCATIONS USED ! 21841: # ! 21842: # NOTE THAT THE FIRST WORD OF THE BLOCK (NORMALLY B$SCL) ! 21843: # IS NOT USED AND NEED NOT BE SET CORRECTLY (SEE PRTVN) ! 21844: # ! 21845: # (XR) STRING TO BE PRINTED ! 21846: # JSR PRTST CALL TO PRINT STRING ! 21847: # (PROFS) UPDATED PAST CHARS PLACED ! 21848: # ! 21849: prtst: #prc # entry point ! 21850: tstl headp # were headers printed ! 21851: bnequ prst0 ! 21852: jsb prtps # no - print them ! 21853: # ! 21854: # CALL SYSPR ! 21855: # ! 21856: prst0: movl r6,prsva # save wa ! 21857: movl r7,prsvb # save wb ! 21858: clrl r7 # set chars printed count to zero ! 21859: # ! 21860: # LOOP TO PRINT SUCCESSIVE LINES FOR LONG STRING ! 21861: # ! 21862: prst1: movl 4*sclen(r9),r6 # load string length ! 21863: subl2 r7,r6 # subtract count of chars already out ! 21864: tstl r6 # jump to exit if none left ! 21865: bnequ 0f ! 21866: jmp prst4 ! 21867: 0: ! 21868: movl r10,-(sp) # else stack entry xl ! 21869: movl r9,-(sp) # save argument ! 21870: movl r9,r10 # copy for eventual move ! 21871: movl prlen,r9 # load print buffer length ! 21872: subl2 profs,r9 # get chars left in print buffer ! 21873: tstl r9 # skip if room left on this line ! 21874: bnequ prst2 ! 21875: jsb prtnl # else print this line ! 21876: movl prlen,r9 # and set full width available ! 21877: #page ! 21878: # ! 21879: # PRTST (CONTINUED) ! 21880: # ! 21881: # HERE WITH CHARS TO PRINT AND SOME ROOM IN BUFFER ! 21882: # ! 21883: prst2: cmpl r6,r9 # jump if room for rest of string ! 21884: blequ prst3 ! 21885: movl r9,r6 # else set to fill line ! 21886: # ! 21887: # MERGE HERE WITH CHARACTER COUNT IN WA ! 21888: # ! 21889: prst3: movl prbuf,r9 # point to print buffer ! 21890: movab cfp$f(r10)[r7],r10 # point to location in string ! 21891: movl profs,r11 # [get in scratch register] ! 21892: movab cfp$f(r9)[r11],r9# point to location in buffer ! 21893: addl2 r6,r7 # bump string chars count ! 21894: addl2 r6,profs # bump buffer pointer ! 21895: movl r7,prsvc # preserve char counter ! 21896: jsb sbmvc # move characters to buffer ! 21897: movl prsvc,r7 # recover char counter ! 21898: movl (sp)+,r9 # restore argument pointer ! 21899: movl (sp)+,r10 # restore entry xl ! 21900: jmp prst1 # loop back to test for more ! 21901: # ! 21902: # HERE TO EXIT AFTER PRINTING STRING ! 21903: # ! 21904: prst4: movl prsvb,r7 # restore entry wb ! 21905: movl prsva,r6 # restore entry wa ! 21906: rsb # return to prtst caller ! 21907: #enp # end procedure prtst ! 21908: #page ! 21909: # ! 21910: # PRTTR -- PRINT TO TERMINAL ! 21911: # ! 21912: # CALLED TO PRINT CONTENTS OF STANDARD PRINT BUFFER TO ! 21913: # ONLINE TERMINAL. CLEARS BUFFER DOWN AND RESETS PROFS. ! 21914: # ! 21915: # JSR PRTTR CALL FOR PRINT ! 21916: # (WA,WB) DESTROYED ! 21917: # ! 21918: prttr: #prc # entry point ! 21919: movl r9,-(sp) # save xr ! 21920: jsb prtic # print buffer contents ! 21921: movl prbuf,r9 # point to print bfr to clear it ! 21922: movl prlnw,r6 # get buffer length ! 21923: addl2 $4*schar,r9 # point past scblk header ! 21924: movl nullw,r7 # get blanks ! 21925: # ! 21926: # LOOP TO CLEAR BUFFER ! 21927: # ! 21928: prtt1: movl r7,(r9)+ # clear a word ! 21929: sobgtr r6,prtt1 # loop ! 21930: clrl profs # reset profs ! 21931: movl (sp)+,r9 # restore xr ! 21932: rsb # return ! 21933: #enp # end procedure prttr ! 21934: #page ! 21935: # ! 21936: # PRTVL -- PRINT A VALUE ! 21937: # ! 21938: # PRTVL PLACES AN APPROPRIATE CHARACTER REPRESENTATION OF ! 21939: # A DATA VALUE IN THE PRINT BUFFER FOR DUMP/TRACE USE. ! 21940: # ! 21941: # (XR) VALUE TO BE PRINTED ! 21942: # JSR PRTVL CALL TO PRINT VALUE ! 21943: # (WA,WB,WC,RA) DESTROYED ! 21944: # ! 21945: prtvl: #prc # entry point, recursive ! 21946: movl r10,-(sp) # save entry xl ! 21947: movl r9,-(sp) # save argument ! 21948: jsb sbchk # check for stack overflow ! 21949: # ! 21950: # LOOP BACK HERE AFTER FINDING A TRAP BLOCK (TRBLK) ! 21951: # ! 21952: prv01: movl 4*idval(r9),prvsi# copy idval (if any) ! 21953: movl (r9),r10 # load first word of block ! 21954: movzwl -2(r10),r10 # load entry point id ! 21955: casel r10,$0,$bl$$t # switch on block type ! 21956: 5: ! 21957: .word prv05-5b # arblk ! 21958: .word prv15-5b # bcblk ! 21959: .word prv02-5b ! 21960: .word prv02-5b ! 21961: .word prv08-5b # icblk ! 21962: .word prv09-5b # nmblk ! 21963: .word prv02-5b ! 21964: .word prv02-5b ! 21965: .word prv02-5b ! 21966: .word prv08-5b # rcblk ! 21967: .word prv11-5b # scblk ! 21968: .word prv12-5b # seblk ! 21969: .word prv13-5b # tbblk ! 21970: .word prv13-5b # vcblk ! 21971: .word prv02-5b ! 21972: .word prv02-5b ! 21973: .word prv10-5b # pdblk ! 21974: .word prv04-5b # trblk ! 21975: #esw # end of switch on block type ! 21976: # ! 21977: # HERE FOR BLOCKS FOR WHICH WE JUST PRINT DATATYPE NAME ! 21978: # ! 21979: prv02: jsb dtype # get datatype name ! 21980: jsb prtst # print datatype name ! 21981: # ! 21982: # COMMON EXIT POINT ! 21983: # ! 21984: prv03: movl (sp)+,r9 # reload argument ! 21985: movl (sp)+,r10 # restore xl ! 21986: rsb # return to prtvl caller ! 21987: # ! 21988: # HERE FOR TRBLK ! 21989: # ! 21990: prv04: movl 4*trval(r9),r9 # load real value ! 21991: jmp prv01 # and loop back ! 21992: #page ! 21993: # ! 21994: # PRTVL (CONTINUED) ! 21995: # ! 21996: # HERE FOR ARRAY (ARBLK) ! 21997: # ! 21998: # PRINT ARRAY ( PROTOTYPE ) BLANK NUMBER IDVAL ! 21999: # ! 22000: prv05: movl r9,r10 # preserve argument ! 22001: movl $scarr,r9 # point to datatype name (array) ! 22002: jsb prtst # print it ! 22003: movl $ch$pp,r6 # load left paren ! 22004: jsb prtch # print left paren ! 22005: addl2 4*arofs(r10),r10# point to prototype ! 22006: movl (r10),r9 # load prototype ! 22007: jsb prtst # print prototype ! 22008: # ! 22009: # VCBLK, TBBLK, BCBLK MERGE HERE FOR ) BLANK NUMBER IDVAL ! 22010: # ! 22011: prv06: movl $ch$rp,r6 # load right paren ! 22012: jsb prtch # print right paren ! 22013: # ! 22014: # PDBLK MERGES HERE TO PRINT BLANK NUMBER IDVAL ! 22015: # ! 22016: prv07: movl $ch$bl,r6 # load blank ! 22017: jsb prtch # print it ! 22018: movl $ch$nm,r6 # load number sign ! 22019: jsb prtch # print it ! 22020: movl prvsi,r5 # get idval ! 22021: jsb prtin # print id number ! 22022: jmp prv03 # back to exit ! 22023: # ! 22024: # HERE FOR INTEGER (ICBLK), REAL (RCBLK) ! 22025: # ! 22026: # PRINT CHARACTER REPRESENTATION OF VALUE ! 22027: # ! 22028: prv08: movl r9,-(sp) # stack argument for gtstg ! 22029: jsb gtstg # convert to string ! 22030: .long invalid$ # error return is impossible ! 22031: jsb prtst # print the string ! 22032: movl r9,dnamp # delete garbage string from storage ! 22033: jmp prv03 # back to exit ! 22034: #page ! 22035: # ! 22036: # PRTVL (CONTINUED) ! 22037: # ! 22038: # NAME (NMBLK) ! 22039: # ! 22040: # FOR PSEUDO-VARIABLE, JUST PRINT DATATYPE NAME (NAME) ! 22041: # FOR ALL OTHER NAMES, PRINT DOT FOLLOWED BY NAME REP ! 22042: # ! 22043: prv09: movl 4*nmbas(r9),r10 # load name base ! 22044: movl (r10),r6 # load first word of block ! 22045: cmpl r6,$b$kvt # just print name if keyword ! 22046: bnequ 0f ! 22047: jmp prv02 ! 22048: 0: ! 22049: cmpl r6,$b$evt # just print name if expression var ! 22050: bnequ 0f ! 22051: jmp prv02 ! 22052: 0: ! 22053: movl $ch$dt,r6 # else get dot ! 22054: jsb prtch # and print it ! 22055: movl 4*nmofs(r9),r6 # load name offset ! 22056: jsb prtnm # print name ! 22057: jmp prv03 # back to exit ! 22058: # ! 22059: # PROGRAM DATATYPE (PDBLK) ! 22060: # ! 22061: # PRINT DATATYPE NAME CH$BL CH$NM IDVAL ! 22062: # ! 22063: prv10: jsb dtype # get datatype name ! 22064: jsb prtst # print datatype name ! 22065: jmp prv07 # merge back to print id ! 22066: # ! 22067: # HERE FOR STRING (SCBLK) ! 22068: # ! 22069: # PRINT QUOTE STRING-CHARACTERS QUOTE ! 22070: # ! 22071: prv11: movl $ch$sq,r6 # load single quote ! 22072: jsb prtch # print quote ! 22073: jsb prtst # print string value ! 22074: jsb prtch # print another quote ! 22075: jmp prv03 # back to exit ! 22076: #page ! 22077: # ! 22078: # PRTVL (CONTINUED) ! 22079: # ! 22080: # HERE FOR SIMPLE EXPRESSION (SEBLK) ! 22081: # ! 22082: # PRINT ASTERISK VARIABLE-NAME ! 22083: # ! 22084: prv12: movl $ch$as,r6 # load asterisk ! 22085: jsb prtch # print asterisk ! 22086: movl 4*sevar(r9),r9 # load variable pointer ! 22087: jsb prtvn # print variable name ! 22088: jmp prv03 # jump back to exit ! 22089: # ! 22090: # HERE FOR TABLE (TBBLK) AND ARRAY (VCBLK) ! 22091: # ! 22092: # PRINT DATATYPE ( PROTOTYPE ) BLANK NUMBER IDVAL ! 22093: # ! 22094: prv13: movl r9,r10 # preserve argument ! 22095: jsb dtype # get datatype name ! 22096: jsb prtst # print datatype name ! 22097: movl $ch$pp,r6 # load left paren ! 22098: jsb prtch # print left paren ! 22099: movl 4*tblen(r10),r6 # load length of block (=vclen) ! 22100: ashl $-2,r6,r6 # convert to word count ! 22101: subl2 $tbsi$,r6 # allow for standard fields ! 22102: cmpl (r10),$b$tbt # jump if table ! 22103: beqlu prv14 ! 22104: addl2 $vctbd,r6 # for vcblk, adjust size ! 22105: # ! 22106: # PRINT PROTOTYPE ! 22107: # ! 22108: prv14: movl r6,r5 # move as integer ! 22109: jsb prtin # print integer prototype ! 22110: jmp prv06 # merge back for rest ! 22111: #page ! 22112: # ! 22113: # PRTVL (CONTINUED) ! 22114: # ! 22115: # HERE FOR BUFFER (BCBLK) ! 22116: # ! 22117: prv15: movl r9,r10 # preserve argument ! 22118: movl $scbuf,r9 # point to datatype name (buffer) ! 22119: jsb prtst # print it ! 22120: movl $ch$pp,r6 # load left paren ! 22121: jsb prtch # print left paren ! 22122: movl 4*bcbuf(r10),r9 # point to bfblk ! 22123: movl 4*bfalc(r9),r5 # load allocation size ! 22124: jsb prtin # print it ! 22125: movl $ch$cm,r6 # load comma ! 22126: jsb prtch # print it ! 22127: movl 4*bclen(r10),r5 # load defined length ! 22128: jsb prtin # print it ! 22129: jmp prv06 # merge to finish up ! 22130: #enp # end procedure prtvl ! 22131: #page ! 22132: # ! 22133: # PRTVN -- PRINT NATURAL VARIABLE NAME ! 22134: # ! 22135: # PRTVN PRINTS THE NAME OF A NATURAL VARIABLE ! 22136: # ! 22137: # (XR) POINTER TO VRBLK ! 22138: # JSR PRTVN CALL TO PRINT VARIABLE NAME ! 22139: # ! 22140: prtvn: #prc # entry point ! 22141: movl r9,-(sp) # stack vrblk pointer ! 22142: addl2 $4*vrsof,r9 # point to possible string name ! 22143: tstl 4*sclen(r9) # jump if not system variable ! 22144: bnequ prvn1 ! 22145: movl 4*vrsvo(r9),r9 # point to svblk with name ! 22146: # ! 22147: # MERGE HERE WITH DUMMY SCBLK POINTER IN XR ! 22148: # ! 22149: prvn1: jsb prtst # print string name of variable ! 22150: movl (sp)+,r9 # restore vrblk pointer ! 22151: rsb # return to prtvn caller ! 22152: #enp # end procedure prtvn ! 22153: #page ! 22154: # ! 22155: # RCBLD -- BUILD A REAL BLOCK ! 22156: # ! 22157: # (RA) REAL VALUE FOR RCBLK ! 22158: # JSR RCBLD CALL TO BUILD REAL BLOCK ! 22159: # (XR) POINTER TO RESULT RCBLK ! 22160: # (WA) DESTROYED ! 22161: # ! 22162: rcbld: #prc # entry point ! 22163: movl dnamp,r9 # load pointer to next available loc ! 22164: addl2 $4*rcsi$,r9 # point past new rcblk ! 22165: cmpl r9,dname # jump if there is room ! 22166: blequ rcbl1 ! 22167: movl $4*rcsi$,r6 # else load rcblk length ! 22168: jsb alloc # use standard allocator to get block ! 22169: addl2 r6,r9 # point past block to merge ! 22170: # ! 22171: # MERGE HERE WITH XR POINTING PAST THE BLOCK OBTAINED ! 22172: # ! 22173: rcbl1: movl r9,dnamp # set new pointer ! 22174: subl2 $4*rcsi$,r9 # point back to start of block ! 22175: movl $b$rcl,(r9) # store type word ! 22176: movf r2,4*rcval(r9) # store real value in rcblk ! 22177: rsb # return to rcbld caller ! 22178: #enp # end procedure rcbld ! 22179: #page ! 22180: # ! 22181: # READR -- READ NEXT SOURCE IMAGE AT COMPILE TIME ! 22182: # ! 22183: # READR IS USED TO READ THE NEXT SOURCE IMAGE. TO PROCESS ! 22184: # CONTINUATION CARDS PROPERLY, THE COMPILER MUST READ ONE ! 22185: # LINE AHEAD. THUS READR DOES NOT DESTROY THE CURRENT IMAGE ! 22186: # SEE ALSO THE NEXTS ROUTINE WHICH ACTUALLY GETS THE IMAGE. ! 22187: # ! 22188: # JSR READR CALL TO READ NEXT IMAGE ! 22189: # (XR) PTR TO NEXT IMAGE (0 IF NONE) ! 22190: # (R$CNI) COPY OF POINTER ! 22191: # (WA,WB,WC,XL) DESTROYED ! 22192: # ! 22193: readr: #prc # entry point ! 22194: movl r$cni,r9 # get ptr to next image ! 22195: tstl r9 # exit if already read ! 22196: bnequ read3 ! 22197: cmpl stage,$stgic # exit if not initial compile ! 22198: bnequ read3 ! 22199: movl cswin,r6 # max read length ! 22200: jsb alocs # allocate buffer ! 22201: jsb sysrd # read input image ! 22202: .long read4 # jump if end of file ! 22203: movl sp,r7 # set trimr to perform trim ! 22204: cmpl 4*sclen(r9),cswin# use smaller of string lnth .. ! 22205: blequ read1 ! 22206: movl cswin,4*sclen(r9)# ... and xxx of -inxxx ! 22207: # ! 22208: # PERFORM THE TRIM ! 22209: # ! 22210: read1: jsb trimr # trim trailing blanks ! 22211: # ! 22212: # MERGE HERE AFTER READ ! 22213: # ! 22214: read2: movl r9,r$cni # store copy of pointer ! 22215: # ! 22216: # MERGE HERE IF NO READ ATTEMPTED ! 22217: # ! 22218: read3: rsb # return to readr caller ! 22219: # ! 22220: # HERE ON END OF FILE ! 22221: # ! 22222: read4: movl r9,dnamp # pop unused scblk ! 22223: clrl r9 # zero ptr as result ! 22224: jmp read2 # merge ! 22225: #enp # end procedure readr ! 22226: #page ! 22227: # ! 22228: # SBSTR -- BUILD A SUBSTRING ! 22229: # ! 22230: # (XL) PTR TO SCBLK/BFBLK WITH CHARS ! 22231: # (WA) NUMBER OF CHARS IN SUBSTRING ! 22232: # (WB) OFFSET TO FIRST CHAR IN SCBLK ! 22233: # JSR SBSTR CALL TO BUILD SUBSTRING ! 22234: # (XR) PTR TO NEW SCBLK WITH SUBSTRING ! 22235: # (XL) ZERO ! 22236: # (WA,WB,WC,XL,IA) DESTROYED ! 22237: # ! 22238: # NOTE THAT SBSTR IS CALLED WITH A DUMMY STRING POINTER ! 22239: # (POINTING INTO A VRBLK OR SVBLK) TO COPY THE NAME OF A ! 22240: # VARIABLE AS A STANDARD STRING VALUE. ! 22241: # ! 22242: sbstr: #prc # entry point ! 22243: tstl r6 # jump if null substring ! 22244: beqlu sbst2 ! 22245: jsb alocs # else allocate scblk ! 22246: movl r8,r6 # move number of characters ! 22247: movl r9,r8 # save ptr to new scblk ! 22248: movab cfp$f(r10)[r7],r10 # prepare to load chars from old blk ! 22249: movab cfp$f(r9),r9 # prepare to store chars in new blk ! 22250: jsb sbmvc # move characters to new string ! 22251: movl r8,r9 # then restore scblk pointer ! 22252: # ! 22253: # RETURN POINT ! 22254: # ! 22255: sbst1: clrl r10 # clear garbage pointer in xl ! 22256: rsb # return to sbstr caller ! 22257: # ! 22258: # HERE FOR NULL SUBSTRING ! 22259: # ! 22260: sbst2: movl $nulls,r9 # set null string as result ! 22261: jmp sbst1 # return ! 22262: #enp # end procedure sbstr ! 22263: #page ! 22264: # ! 22265: # SCANE -- SCAN AN ELEMENT ! 22266: # ! 22267: # SCANE IS CALLED AT COMPILE TIME (BY EXPAN ,CMPIL,CNCRD) ! 22268: # TO SCAN ONE ELEMENT FROM THE INPUT IMAGE. ! 22269: # ! 22270: # (SCNCC) NON-ZERO IF CALLED FROM CNCRD ! 22271: # JSR SCANE CALL TO SCAN ELEMENT ! 22272: # (XR) RESULT POINTER (SEE BELOW) ! 22273: # (XL) SYNTAX TYPE CODE (T$XXX) ! 22274: # ! 22275: # THE FOLLOWING GLOBAL LOCATIONS ARE USED. ! 22276: # ! 22277: # R$CIM POINTER TO STRING BLOCK (SCBLK) ! 22278: # FOR CURRENT INPUT IMAGE. ! 22279: # ! 22280: # R$CNI POINTER TO NEXT INPUT IMAGE STRING ! 22281: # POINTER (ZERO IF NONE). ! 22282: # ! 22283: # R$SCP SAVE POINTER (EXIT XR) FROM LAST ! 22284: # CALL IN CASE RESCAN IS SET. ! 22285: # ! 22286: # SCNBL THIS LOCATION IS SET NON-ZERO ON ! 22287: # EXIT IF SCANE SCANNED PAST BLANKS ! 22288: # BEFORE LOCATING THE CURRENT ELEMENT ! 22289: # THE END OF A LINE COUNTS AS BLANKS. ! 22290: # ! 22291: # SCNCC CNCRD SETS THIS NON-ZERO TO SCAN ! 22292: # CONTROL CARD NAMES AND CLEARS IT ! 22293: # ON RETURN ! 22294: # ! 22295: # SCNIL LENGTH OF CURRENT INPUT IMAGE ! 22296: # ! 22297: # SCNGO IF SET NON-ZERO ON ENTRY, F AND S ! 22298: # ARE RETURNED AS SEPARATE SYNTAX ! 22299: # TYPES (NOT LETTERS) (GOTO PRO- ! 22300: # CESSING). SCNGO IS RESET ON EXIT. ! 22301: # ! 22302: # SCNPT OFFSET TO CURRENT LOC IN R$CIM ! 22303: # ! 22304: # SCNRS IF SET NON-ZERO ON ENTRY, SCANE ! 22305: # RETURNS THE SAME RESULT AS ON THE ! 22306: # LAST CALL (RESCAN). SCNRS IS RESET ! 22307: # ON EXIT FROM ANY CALL TO SCANE. ! 22308: # ! 22309: # SCNTP SAVE SYNTAX TYPE FROM LAST ! 22310: # CALL (IN CASE RESCAN IS SET). ! 22311: #page ! 22312: # ! 22313: # SCANE (CONTINUED) ! 22314: # ! 22315: # ! 22316: # ! 22317: # ELEMENT SCANNED XL XR ! 22318: # --------------- -- -- ! 22319: # ! 22320: # CONTROL CARD NAME 0 POINTER TO SCBLK FOR NAME ! 22321: # ! 22322: # UNARY OPERATOR T$UOP PTR TO OPERATOR DVBLK ! 22323: # ! 22324: # LEFT PAREN T$LPR T$LPR ! 22325: # ! 22326: # LEFT BRACKET T$LBR T$LBR ! 22327: # ! 22328: # COMMA T$CMA T$CMA ! 22329: # ! 22330: # FUNCTION CALL T$FNC PTR TO FUNCTION VRBLK ! 22331: # ! 22332: # VARIABLE T$VAR PTR TO VRBLK ! 22333: # ! 22334: # STRING CONSTANT T$CON PTR TO SCBLK ! 22335: # ! 22336: # INTEGER CONSTANT T$CON PTR TO ICBLK ! 22337: # ! 22338: # REAL CONSTANT T$CON PTR TO RCBLK ! 22339: # ! 22340: # BINARY OPERATOR T$BOP PTR TO OPERATOR DVBLK ! 22341: # ! 22342: # RIGHT PAREN T$RPR T$RPR ! 22343: # ! 22344: # RIGHT BRACKET T$RBR T$RBR ! 22345: # ! 22346: # COLON T$COL T$COL ! 22347: # ! 22348: # SEMI-COLON T$SMC T$SMC ! 22349: # ! 22350: # F (SCNGO NE 0) T$FGO T$FGO ! 22351: # ! 22352: # S (SCNGO NE 0) T$SGO T$SGO ! 22353: #page ! 22354: # ! 22355: # SCANE (CONTINUED) ! 22356: # ! 22357: # ENTRY POINT ! 22358: # ! 22359: scane: #prc # entry point ! 22360: clrl scnbl # reset blanks flag ! 22361: movl r6,scnsa # save wa ! 22362: movl r7,scnsb # save wb ! 22363: movl r8,scnsc # save wc ! 22364: tstl scnrs # jump if no rescan ! 22365: beqlu scn03 ! 22366: # ! 22367: # HERE FOR RESCAN REQUEST ! 22368: # ! 22369: movl scntp,r10 # set previous returned scan type ! 22370: movl r$scp,r9 # set previous returned pointer ! 22371: clrl scnrs # reset rescan switch ! 22372: jmp scn13 # jump to exit ! 22373: # ! 22374: # COME HERE TO READ NEW IMAGE TO TEST FOR CONTINUATION ! 22375: # ! 22376: scn01: jsb readr # read next image ! 22377: movl $4*dvubs,r7 # set wb for not reading name ! 22378: tstl r9 # treat as semi-colon if none ! 22379: bnequ 0f ! 22380: jmp scn30 ! 22381: 0: ! 22382: movab cfp$f(r9),r9 # else point to first character ! 22383: movzbl (r9),r8 # load first character ! 22384: cmpl r8,$ch$dt # jump if dot for continuation ! 22385: beqlu scn02 ! 22386: cmpl r8,$ch$pl # else treat as semicolon unless plus ! 22387: beqlu 0f ! 22388: jmp scn30 ! 22389: 0: ! 22390: # ! 22391: # HERE FOR CONTINUATION LINE ! 22392: # ! 22393: scn02: jsb nexts # acquire next source image ! 22394: movl $num01,scnpt # set scan pointer past continuation ! 22395: movl sp,scnbl # set blanks flag ! 22396: #page ! 22397: # ! 22398: # SCANE (CONTINUED) ! 22399: # ! 22400: # MERGE HERE TO SCAN NEXT ELEMENT ON CURRENT LINE ! 22401: # ! 22402: scn03: movl scnpt,r6 # load current offset ! 22403: cmpl r6,scnil # check continuation if end ! 22404: bnequ 0f ! 22405: jmp scn01 ! 22406: 0: ! 22407: movl r$cim,r10 # point to current line ! 22408: movab cfp$f(r10)[r6],r10 # point to current character ! 22409: movl r6,scnse # set start of element location ! 22410: movl $opdvs,r8 # point to operator dv list ! 22411: movl $4*dvubs,r7 # set constant for operator circuit ! 22412: jmp scn06 # start scanning ! 22413: # ! 22414: # LOOP HERE TO IGNORE LEADING BLANKS AND TABS ! 22415: # ! 22416: scn05: tstl r7 # jump if trailing ! 22417: bnequ 0f ! 22418: jmp scn10 ! 22419: 0: ! 22420: incl scnse # increment start of element ! 22421: cmpl r6,scnil # jump if end of image ! 22422: bnequ 0f ! 22423: jmp scn01 ! 22424: 0: ! 22425: movl sp,scnbl # note blanks seen ! 22426: # ! 22427: # THE FOLLOWING JUMP IS USED REPEATEDLY FOR SCANNING OUT ! 22428: # THE CHARACTERS OF A NUMERIC CONSTANT OR VARIABLE NAME. ! 22429: # THE REGISTERS ARE USED AS FOLLOWS. ! 22430: # ! 22431: # (XR) SCRATCH ! 22432: # (XL) PTR TO NEXT CHARACTER ! 22433: # (WA) CURRENT SCAN OFFSET ! 22434: # (WB) *DVUBS (0 IF SCANNING NAME,CONST) ! 22435: # (WC) =OPDVS (0 IF SCANNING CONSTANT) ! 22436: # ! 22437: scn06: movzbl (r10)+,r9 # get next character ! 22438: incl r6 # bump scan offset ! 22439: movl r6,scnpt # store offset past char scanned ! 22440: cmpl $cfp$u,r9 # quick check for other char ! 22441: bgtru 0f ! 22442: jmp scn07 ! 22443: 0: ! 22444: casel r9,$0,$cfp$u # switch on scanned character ! 22445: 5: ! 22446: # ! 22447: # SWITCH TABLE FOR SWITCH ON CHARACTER ! 22448: # ! 22449: #page ! 22450: # ! 22451: # SCANE (CONTINUED) ! 22452: # ! 22453: #page ! 22454: # ! 22455: # SCANE (CONTINUED) ! 22456: # ! 22457: .word scn07-5b ! 22458: .word scn07-5b ! 22459: .word scn07-5b ! 22460: .word scn07-5b ! 22461: .word scn07-5b ! 22462: .word scn07-5b ! 22463: .word scn07-5b ! 22464: .word scn07-5b ! 22465: .word scn07-5b ! 22466: .word scn05-5b # horizontal tab ! 22467: .word scn07-5b ! 22468: .word scn07-5b ! 22469: .word scn07-5b ! 22470: .word scn07-5b ! 22471: .word scn07-5b ! 22472: .word scn07-5b ! 22473: .word scn07-5b ! 22474: .word scn07-5b ! 22475: .word scn07-5b ! 22476: .word scn07-5b ! 22477: .word scn07-5b ! 22478: .word scn07-5b ! 22479: .word scn07-5b ! 22480: .word scn07-5b ! 22481: .word scn07-5b ! 22482: .word scn07-5b ! 22483: .word scn07-5b ! 22484: .word scn07-5b ! 22485: .word scn07-5b ! 22486: .word scn07-5b ! 22487: .word scn07-5b ! 22488: .word scn07-5b ! 22489: .word scn05-5b # blank ! 22490: .word scn37-5b # exclamation mark ! 22491: .word scn17-5b # double quote ! 22492: .word scn41-5b # number sign ! 22493: .word scn36-5b # dollar ! 22494: .word scn38-5b # percent ! 22495: .word scn44-5b # ampersand ! 22496: .word scn16-5b # single quote ! 22497: .word scn25-5b # left paren ! 22498: .word scn26-5b # right paren ! 22499: .word scn49-5b # asterisk ! 22500: .word scn33-5b # plus ! 22501: .word scn31-5b # comma ! 22502: .word scn34-5b # minus ! 22503: .word scn32-5b # dot ! 22504: .word scn40-5b # slash ! 22505: .word scn08-5b # digit 0 ! 22506: .word scn08-5b # digit 1 ! 22507: .word scn08-5b # digit 2 ! 22508: .word scn08-5b # digit 3 ! 22509: .word scn08-5b # digit 4 ! 22510: .word scn08-5b # digit 5 ! 22511: .word scn08-5b # digit 6 ! 22512: .word scn08-5b # digit 7 ! 22513: .word scn08-5b # digit 8 ! 22514: .word scn08-5b # digit 9 ! 22515: .word scn29-5b # colon ! 22516: .word scn30-5b # semi-colon ! 22517: .word scn28-5b # left bracket ! 22518: .word scn46-5b # equal ! 22519: .word scn27-5b # right bracket ! 22520: .word scn45-5b # question mark ! 22521: .word scn42-5b # at ! 22522: .word scn09-5b # letter a ! 22523: .word scn09-5b # letter b ! 22524: .word scn09-5b # letter c ! 22525: .word scn09-5b # letter d ! 22526: .word scn09-5b # letter e ! 22527: .word scn20-5b # letter f ! 22528: .word scn09-5b # letter g ! 22529: .word scn09-5b # letter h ! 22530: .word scn09-5b # letter i ! 22531: .word scn09-5b # letter j ! 22532: .word scn09-5b # letter k ! 22533: .word scn09-5b # letter l ! 22534: .word scn09-5b # letter m ! 22535: .word scn09-5b # letter n ! 22536: .word scn09-5b # letter o ! 22537: .word scn09-5b # letter p ! 22538: .word scn09-5b # letter q ! 22539: .word scn09-5b # letter r ! 22540: .word scn21-5b # letter s ! 22541: .word scn09-5b # letter t ! 22542: .word scn09-5b # letter u ! 22543: .word scn09-5b # letter v ! 22544: .word scn09-5b # letter w ! 22545: .word scn09-5b # letter x ! 22546: .word scn09-5b # letter y ! 22547: .word scn09-5b # letter z ! 22548: .word scn28-5b # left bracket ! 22549: .word scn07-5b ! 22550: .word scn27-5b # right bracket ! 22551: .word scn07-5b ! 22552: .word scn24-5b # underline ! 22553: .word scn07-5b ! 22554: .word scn09-5b # shifted a ! 22555: .word scn09-5b # shifted b ! 22556: .word scn09-5b # shifted c ! 22557: .word scn09-5b # shifted d ! 22558: .word scn09-5b # shifted e ! 22559: .word scn20-5b # shifted f ! 22560: .word scn09-5b # shifted g ! 22561: .word scn09-5b # shifted h ! 22562: .word scn09-5b # shifted i ! 22563: .word scn09-5b # shifted j ! 22564: .word scn09-5b # shifted k ! 22565: .word scn09-5b # shifted l ! 22566: .word scn09-5b # shifted m ! 22567: .word scn09-5b # shifted n ! 22568: .word scn09-5b # shifted o ! 22569: .word scn09-5b # shifted p ! 22570: .word scn09-5b # shifted q ! 22571: .word scn09-5b # shifted r ! 22572: .word scn21-5b # shifted s ! 22573: .word scn09-5b # shifted t ! 22574: .word scn09-5b # shifted u ! 22575: .word scn09-5b # shifted v ! 22576: .word scn09-5b # shifted w ! 22577: .word scn09-5b # shifted x ! 22578: .word scn09-5b # shifted y ! 22579: .word scn09-5b # shifted z ! 22580: .word scn07-5b ! 22581: .word scn43-5b # vertical bar ! 22582: .word scn07-5b ! 22583: .word scn35-5b # not ! 22584: .word scn07-5b ! 22585: #esw # end switch on character ! 22586: # ! 22587: # HERE FOR ILLEGAL CHARACTER (UNDERLINE MERGES) ! 22588: # ! 22589: scn07: tstl r7 # jump if scanning name or constant ! 22590: bnequ 0f ! 22591: jmp scn10 ! 22592: 0: ! 22593: jmp er_230 # syntax error. illegal character ! 22594: #page ! 22595: # ! 22596: # SCANE (CONTINUED) ! 22597: # ! 22598: # HERE FOR DIGITS 0-9 ! 22599: # ! 22600: scn08: tstl r7 # keep scanning if name/constant ! 22601: bnequ 0f ! 22602: jmp scn09 ! 22603: 0: ! 22604: clrl r8 # else set flag for scanning constant ! 22605: # ! 22606: # HERE FOR LETTER. LOOP HERE WHEN SCANNING NAME/CONSTANT ! 22607: # ! 22608: scn09: cmpl r6,scnil # jump if end of image ! 22609: beqlu scn11 ! 22610: clrl r7 # set flag for scanning name/const ! 22611: jmp scn06 # merge back to continue scan ! 22612: # ! 22613: # COME HERE FOR DELIMITER ENDING NAME OR CONSTANT ! 22614: # ! 22615: scn10: decl r6 # reset offset to point to delimiter ! 22616: # ! 22617: # COME HERE AFTER FINISHING SCAN OF NAME OR CONSTANT ! 22618: # ! 22619: scn11: movl r6,scnpt # store updated scan offset ! 22620: movl scnse,r7 # point to start of element ! 22621: subl2 r7,r6 # get number of characters ! 22622: movl r$cim,r10 # point to line image ! 22623: tstl r8 # jump if name ! 22624: bnequ scn15 ! 22625: # ! 22626: # HERE AFTER SCANNING OUT NUMERIC CONSTANT ! 22627: # ! 22628: jsb sbstr # get string for constant ! 22629: movl r9,dnamp # delete from storage (not needed) ! 22630: jsb gtnum # convert to numeric ! 22631: .long scn14 # jump if conversion failure ! 22632: # ! 22633: # MERGE HERE TO EXIT WITH CONSTANT ! 22634: # ! 22635: scn12: movl $t$con,r10 # set result type of constant ! 22636: #page ! 22637: # ! 22638: # SCANE (CONTINUED) ! 22639: # ! 22640: # COMMON EXIT POINT (XR,XL) SET ! 22641: # ! 22642: scn13: movl scnsa,r6 # restore wa ! 22643: movl scnsb,r7 # restore wb ! 22644: movl scnsc,r8 # restore wc ! 22645: movl r9,r$scp # save xr in case rescan ! 22646: movl r10,scntp # save xl in case rescan ! 22647: clrl scngo # reset possible goto flag ! 22648: rsb # return to scane caller ! 22649: # ! 22650: # HERE IF CONVERSION ERROR ON NUMERIC ITEM ! 22651: # ! 22652: scn14: jmp er_231 # syntax error. invalid numeric item ! 22653: # ! 22654: # HERE AFTER SCANNING OUT VARIABLE NAME ! 22655: # ! 22656: scn15: jsb sbstr # build string name of variable ! 22657: tstl scncc # return if cncrd call ! 22658: beqlu 0f ! 22659: jmp scn13 ! 22660: 0: ! 22661: jsb gtnvr # locate/build vrblk ! 22662: .long invalid$ # dummy (unused) error return ! 22663: movl $t$var,r10 # set type as variable ! 22664: jmp scn13 # back to exit ! 22665: # ! 22666: # HERE FOR SINGLE QUOTE (START OF STRING CONSTANT) ! 22667: # ! 22668: scn16: tstl r7 # terminator if scanning name or cnst ! 22669: bnequ 0f ! 22670: jmp scn10 ! 22671: 0: ! 22672: movl $ch$sq,r7 # set terminator as single quote ! 22673: jmp scn18 # merge ! 22674: # ! 22675: # HERE FOR DOUBLE QUOTE (START OF STRING CONSTANT) ! 22676: # ! 22677: scn17: tstl r7 # terminator if scanning name or cnst ! 22678: bnequ 0f ! 22679: jmp scn10 ! 22680: 0: ! 22681: movl $ch$dq,r7 # set double quote terminator, merge ! 22682: # ! 22683: # LOOP TO SCAN OUT STRING CONSTANT ! 22684: # ! 22685: scn18: cmpl r6,scnil # error if end of image ! 22686: beqlu scn19 ! 22687: movzbl (r10)+,r8 # else load next character ! 22688: incl r6 # bump offset ! 22689: cmpl r8,r7 # loop back if not terminator ! 22690: bnequ scn18 ! 22691: #page ! 22692: # ! 22693: # SCANE (CONTINUED) ! 22694: # ! 22695: # HERE AFTER SCANNING OUT STRING CONSTANT ! 22696: # ! 22697: movl scnpt,r7 # point to first character ! 22698: movl r6,scnpt # save offset past final quote ! 22699: decl r6 # point back past last character ! 22700: subl2 r7,r6 # get number of characters ! 22701: movl r$cim,r10 # point to input image ! 22702: jsb sbstr # build substring value ! 22703: jmp scn12 # back to exit with constant result ! 22704: # ! 22705: # HERE IF NO MATCHING QUOTE FOUND ! 22706: # ! 22707: scn19: movl r6,scnpt # set updated scan pointer ! 22708: jmp er_232 # syntax error. unmatched string quote ! 22709: # ! 22710: # HERE FOR F (POSSIBLE FAILURE GOTO) ! 22711: # ! 22712: scn20: movl $t$fgo,r9 # set return code for fail goto ! 22713: jmp scn22 # jump to merge ! 22714: # ! 22715: # HERE FOR S (POSSIBLE SUCCESS GOTO) ! 22716: # ! 22717: scn21: movl $t$sgo,r9 # set success goto as return code ! 22718: # ! 22719: # SPECIAL GOTO CASES MERGE HERE ! 22720: # ! 22721: scn22: tstl scngo # treat as normal letter if not goto ! 22722: bnequ 0f ! 22723: jmp scn09 ! 22724: 0: ! 22725: # ! 22726: # MERGE HERE FOR SPECIAL CHARACTER EXIT ! 22727: # ! 22728: scn23: tstl r7 # jump if end of name/constant ! 22729: bnequ 0f ! 22730: jmp scn10 ! 22731: 0: ! 22732: movl r9,r10 # else copy code ! 22733: jmp scn13 # and jump to exit ! 22734: # ! 22735: # HERE FOR UNDERLINE ! 22736: # ! 22737: scn24: tstl r7 # part of name if scanning name ! 22738: bnequ 0f ! 22739: jmp scn09 ! 22740: 0: ! 22741: jmp scn07 # else illegal ! 22742: #page ! 22743: # ! 22744: # SCANE (CONTINUED) ! 22745: # ! 22746: # HERE FOR LEFT PAREN ! 22747: # ! 22748: scn25: movl $t$lpr,r9 # set left paren return code ! 22749: tstl r7 # return left paren unless name ! 22750: bnequ scn23 ! 22751: tstl r8 # delimiter if scanning constant ! 22752: bnequ 0f ! 22753: jmp scn10 ! 22754: 0: ! 22755: # ! 22756: # HERE FOR LEFT PAREN AFTER NAME (FUNCTION CALL) ! 22757: # ! 22758: movl scnse,r7 # point to start of name ! 22759: movl r6,scnpt # set pointer past left paren ! 22760: decl r6 # point back past last char of name ! 22761: subl2 r7,r6 # get name length ! 22762: movl r$cim,r10 # point to input image ! 22763: jsb sbstr # get string name for function ! 22764: jsb gtnvr # locate/build vrblk ! 22765: .long invalid$ # dummy (unused) error return ! 22766: movl $t$fnc,r10 # set code for function call ! 22767: jmp scn13 # back to exit ! 22768: # ! 22769: # PROCESSING FOR SPECIAL CHARACTERS ! 22770: # ! 22771: scn26: movl $t$rpr,r9 # right paren, set code ! 22772: jmp scn23 # take special character exit ! 22773: # ! 22774: scn27: movl $t$rbr,r9 # right bracket, set code ! 22775: jmp scn23 # take special character exit ! 22776: # ! 22777: scn28: movl $t$lbr,r9 # left bracket, set code ! 22778: jmp scn23 # take special character exit ! 22779: # ! 22780: scn29: movl $t$col,r9 # colon, set code ! 22781: jmp scn23 # take special character exit ! 22782: # ! 22783: scn30: movl $t$smc,r9 # semi-colon, set code ! 22784: jmp scn23 # take special character exit ! 22785: # ! 22786: scn31: movl $t$cma,r9 # comma, set code ! 22787: jmp scn23 # take special character exit ! 22788: #page ! 22789: # ! 22790: # SCANE (CONTINUED) ! 22791: # ! 22792: # HERE FOR OPERATORS. ON ENTRY, WC POINTS TO THE TABLE OF ! 22793: # OPERATOR DOPE VECTORS AND WB IS THE INCREMENT TO STEP ! 22794: # TO THE NEXT PAIR (BINARY/UNARY) OF DOPE VECTORS IN THE ! 22795: # LIST. ON REACHING SCN46, THE POINTER HAS BEEN ADJUSTED TO ! 22796: # POINT TO THE APPROPRIATE PAIR OF DOPE VECTORS. ! 22797: # THE FIRST THREE ENTRIES ARE SPECIAL SINCE THEY CAN OCCUR ! 22798: # AS PART OF A VARIABLE NAME (.) OR CONSTANT (.+-). ! 22799: # ! 22800: scn32: tstl r7 # dot can be part of name or constant ! 22801: bnequ 0f ! 22802: jmp scn09 ! 22803: 0: ! 22804: addl2 r7,r8 # else bump pointer ! 22805: # ! 22806: scn33: tstl r8 # plus can be part of constant ! 22807: bnequ 0f ! 22808: jmp scn09 ! 22809: 0: ! 22810: tstl r7 # plus cannot be part of name ! 22811: bnequ 0f ! 22812: jmp scn48 ! 22813: 0: ! 22814: addl2 r7,r8 # else bump pointer ! 22815: # ! 22816: scn34: tstl r8 # minus can be part of constant ! 22817: bnequ 0f ! 22818: jmp scn09 ! 22819: 0: ! 22820: tstl r7 # minus cannot be part of name ! 22821: bnequ 0f ! 22822: jmp scn48 ! 22823: 0: ! 22824: addl2 r7,r8 # else bump pointer ! 22825: # ! 22826: scn35: addl2 r7,r8 # not ! 22827: scn36: addl2 r7,r8 # dollar ! 22828: scn37: addl2 r7,r8 # exclamation ! 22829: scn38: addl2 r7,r8 # percent ! 22830: scn39: addl2 r7,r8 # asterisk ! 22831: scn40: addl2 r7,r8 # slash ! 22832: scn41: addl2 r7,r8 # number sign ! 22833: scn42: addl2 r7,r8 # at sign ! 22834: scn43: addl2 r7,r8 # vertical bar ! 22835: scn44: addl2 r7,r8 # ampersand ! 22836: scn45: addl2 r7,r8 # question mark ! 22837: # ! 22838: # ALL OPERATORS COME HERE (EQUAL MERGES DIRECTLY) ! 22839: # (WC) POINTS TO THE BINARY/UNARY PAIR OF OPERATOR DVBLKS. ! 22840: # ! 22841: scn46: tstl r7 # operator terminates name/constant ! 22842: bnequ 0f ! 22843: jmp scn10 ! 22844: 0: ! 22845: movl r8,r9 # else copy dv pointer ! 22846: movzbl (r10),r8 # load next character ! 22847: movl $t$bop,r10 # set binary op in case ! 22848: cmpl r6,scnil # should be binary if image end ! 22849: beqlu scn47 ! 22850: cmpl r8,$ch$bl # should be binary if followed by blk ! 22851: beqlu scn47 ! 22852: cmpl r8,$ch$ht # jump if horizontal tab ! 22853: beqlu scn47 ! 22854: cmpl r8,$ch$sm # semicolon can immediately follow = ! 22855: beqlu scn47 ! 22856: # ! 22857: # HERE FOR UNARY OPERATOR ! 22858: # ! 22859: addl2 $4*dvbs$,r9 # point to dv for unary op ! 22860: movl $t$uop,r10 # set type for unary operator ! 22861: cmpl scntp,$t$uok # ok unary if ok preceding element ! 22862: bgtru 0f ! 22863: jmp scn13 ! 22864: 0: ! 22865: #page ! 22866: # ! 22867: # SCANE (CONTINUED) ! 22868: # ! 22869: # MERGE HERE TO REQUIRE PRECEDING BLANKS ! 22870: # ! 22871: scn47: tstl scnbl # all ok if preceding blanks, exit ! 22872: beqlu 0f ! 22873: jmp scn13 ! 22874: 0: ! 22875: # ! 22876: # FAIL OPERATOR IN THIS POSITION ! 22877: # ! 22878: scn48: jmp er_233 # syntax error. invalid use of operator ! 22879: # ! 22880: # HERE FOR ASTERISK, COULD BE ** SUBSTITUTE FOR EXCLAMATION ! 22881: # ! 22882: scn49: tstl r7 # end of name if scanning name ! 22883: bnequ 0f ! 22884: jmp scn10 ! 22885: 0: ! 22886: cmpl r6,scnil # not ** if * at image end ! 22887: beqlu scn39 ! 22888: movl r6,r9 # else save offset past first * ! 22889: movl r6,scnof # save another copy ! 22890: movzbl (r10)+,r6 # load next character ! 22891: cmpl r6,$ch$as # not ** if next char not * ! 22892: bnequ scn50 ! 22893: incl r9 # else step offset past second * ! 22894: cmpl r9,scnil # ok exclam if end of image ! 22895: beqlu scn51 ! 22896: movzbl (r10),r6 # else load next character ! 22897: cmpl r6,$ch$bl # exclamation if blank ! 22898: beqlu scn51 ! 22899: cmpl r6,$ch$ht # exclamation if horizontal tab ! 22900: beqlu scn51 ! 22901: # ! 22902: # UNARY * ! 22903: # ! 22904: scn50: movl scnof,r6 # recover stored offset ! 22905: movl r$cim,r10 # point to line again ! 22906: movab cfp$f(r10)[r6],r10 # point to current char ! 22907: jmp scn39 # merge with unary * ! 22908: # ! 22909: # HERE FOR ** AS SUBSTITUTE FOR EXCLAMATION ! 22910: # ! 22911: scn51: movl r9,scnpt # save scan pointer past 2nd * ! 22912: movl r9,r6 # copy scan pointer ! 22913: jmp scn37 # merge with exclamation ! 22914: #enp # end procedure scane ! 22915: #page ! 22916: # ! 22917: # SCNGF -- SCAN GOTO FIELD ! 22918: # ! 22919: # SCNGF IS CALLED FROM CMPIL TO SCAN AND ANALYZE A GOTO ! 22920: # FIELD INCLUDING THE SURROUNDING BRACKETS OR PARENTHESES. ! 22921: # FOR A NORMAL GOTO, THE RESULT RETURNED IS EITHER A VRBLK ! 22922: # POINTER FOR A SIMPLE LABEL OPERAND, OR A POINTER TO AN ! 22923: # EXPRESSION TREE WITH A SPECIAL OUTER UNARY OPERATOR ! 22924: # (O$GOC). FOR A DIRECT GOTO, THE RESULT RETURNED IS A ! 22925: # POINTER TO AN EXPRESSION TREE WITH THE SPECIAL OUTER ! 22926: # UNARY OPERATOR O$GOD. ! 22927: # ! 22928: # JSR SCNGF CALL TO SCAN GOTO FIELD ! 22929: # (XR) RESULT (SEE ABOVE) ! 22930: # (XL,WA,WB,WC) DESTROYED ! 22931: # ! 22932: scngf: #prc # entry point ! 22933: jsb scane # scan initial element ! 22934: cmpl r10,$t$lpr # skip if left paren (normal goto) ! 22935: beqlu scng1 ! 22936: cmpl r10,$t$lbr # skip if left bracket (direct goto) ! 22937: beqlu scng2 ! 22938: jmp er_234 # syntax error. goto field incorrect ! 22939: # ! 22940: # HERE FOR LEFT PAREN (NORMAL GOTO) ! 22941: # ! 22942: scng1: movl $num01,r7 # set expan flag for normal goto ! 22943: jsb expan # analyze goto field ! 22944: movl $opdvn,r6 # point to opdv for complex goto ! 22945: cmpl r9,statb # jump if not in static (sgd15) ! 22946: blequ scng3 ! 22947: cmpl r9,state # jump to exit if simple label name ! 22948: blequ scng4 ! 22949: jmp scng3 # complex goto - merge ! 22950: # ! 22951: # HERE FOR LEFT BRACKET (DIRECT GOTO) ! 22952: # ! 22953: scng2: movl $num02,r7 # set expan flag for direct goto ! 22954: jsb expan # scan goto field ! 22955: movl $opdvd,r6 # set opdv pointer for direct goto ! 22956: #page ! 22957: # ! 22958: # SCNGF (CONTINUED) ! 22959: # ! 22960: # MERGE HERE TO BUILD OUTER UNARY OPERATOR BLOCK ! 22961: # ! 22962: scng3: movl r6,-(sp) # stack operator dv pointer ! 22963: movl r9,-(sp) # stack pointer to expression tree ! 22964: jsb expop # pop operator off ! 22965: movl (sp)+,r9 # reload new expression tree pointer ! 22966: # ! 22967: # COMMON EXIT POINT ! 22968: # ! 22969: scng4: rsb # return to caller ! 22970: #enp # end procedure scngf ! 22971: #page ! 22972: # ! 22973: # SETVR -- SET VRGET,VRSTO FIELDS OF VRBLK ! 22974: # ! 22975: # SETVR SETS THE PROPER VALUES IN THE VRGET AND VRSTO ! 22976: # FIELDS OF A VRBLK. IT IS CALLED WHENEVER TRBLKS ARE ! 22977: # ADDED OR SUBTRACTED (TRACE,STOPTR,INPUT,OUTPUT,DETACH) ! 22978: # ! 22979: # (XR) POINTER TO VRBLK ! 22980: # JSR SETVR CALL TO SET FIELDS ! 22981: # (XL,WA) DESTROYED ! 22982: # ! 22983: # NOTE THAT SETVR IGNORES THE CALL IF XR DOES NOT POINT ! 22984: # INTO THE STATIC REGION (I.E. IS SOME OTHER NAME BASE) ! 22985: # ! 22986: setvr: #prc # entry point ! 22987: cmpl r9,state # exit if not natural variable ! 22988: bgequ setv1 ! 22989: # ! 22990: # HERE IF WE HAVE A VRBLK ! 22991: # ! 22992: movl r9,r10 # copy vrblk pointer ! 22993: movl $b$vrl,4*vrget(r9) # store normal get value ! 22994: cmpl 4*vrsto(r9),$b$vre # skip if protected variable ! 22995: beqlu setv1 ! 22996: movl $b$vrs,4*vrsto(r9) # store normal store value ! 22997: movl 4*vrval(r10),r10# point to next entry on chain ! 22998: cmpl (r10),$b$trt # jump if end of trblk chain ! 22999: bnequ setv1 ! 23000: movl $b$vra,4*vrget(r9) # store trapped routine address ! 23001: movl $b$vrv,4*vrsto(r9) # set trapped routine address ! 23002: # ! 23003: # MERGE HERE TO EXIT TO CALLER ! 23004: # ! 23005: setv1: rsb # return to setvr caller ! 23006: #enp # end procedure setvr ! 23007: #page ! 23008: # ! 23009: # SORTA -- SORT ARRAY ! 23010: # ! 23011: # ROUTINE TO SORT AN ARRAY OR TABLE ON SAME BASIS AS IN ! 23012: # SITBOL. A TABLE IS CONVERTED TO AN ARRAY, LEAVING TWO ! 23013: # DIMENSIONAL ARRAYS AND VECTORS AS CASES TO BE CONSIDERED. ! 23014: # WHOLE ROWS OF ARRAYS ARE PERMUTED ACCORDING TO THE ! 23015: # ORDERING OF THE KEYS THEY CONTAIN, AND THE STRIDE ! 23016: # REFERRED TO, IS THE THE LENGTH OF A ROW. IT IS ONE ! 23017: # FOR A VECTOR. ! 23018: # THE SORT USED IS HEAPSORT, FUNDAMENTALS OF DATA STRUCTURE ! 23019: # HOROWITZ AND SAHNI, PITMAN 1977, PAGE 347. ! 23020: # IT IS AN ORDER N*LOG(N) ALGORITHM. IN ORDER ! 23021: # TO MAKE IT STABLE, COMPARANDS MAY NOT COMPARE EQUAL. THIS ! 23022: # IS ACHIEVED BY SORTING A COPY ARRAY (REFERRED TO AS THE ! 23023: # SORT ARRAY) CONTAINING AT ITS HIGH ADDRESS END, BYTE ! 23024: # OFFSETS TO THE ROWS TO BE SORTED HELD IN THE ORIGINAL ! 23025: # ARRAY (REFERRED TO AS THE KEY ARRAY). SORTC, THE ! 23026: # COMPARISON ROUTINE, ACCESSES THE KEYS THROUGH THESE ! 23027: # OFFSETS AND IN THE CASE OF EQUALITY, RESOLVES IT BY ! 23028: # COMPARING THE OFFSETS THEMSELVES. THE SORT PERMUTES THE ! 23029: # OFFSETS WHICH ARE THEN USED IN A FINAL OPERATION TO COPY ! 23030: # THE ACTUAL ITEMS INTO THE NEW ARRAY IN SORTED ORDER. ! 23031: # REFERENCES TO ZEROTH ITEM ARE TO NOTIONAL ITEM ! 23032: # PRECEDING FIRST ACTUAL ITEM. ! 23033: # REVERSE SORTING FOR RSORT IS DONE BY HAVING THE LESS THAN ! 23034: # TEST FOR KEYS EFFECTIVELY BE REPLACED BY A ! 23035: # GREATER THAN TEST. ! 23036: # ! 23037: # 1(XS) FIRST ARG - ARRAY OR TABLE ! 23038: # 0(XS) 2ND ARG - INDEX OR PDTYPE NAME ! 23039: # (WA) 0 , NON-ZERO FOR SORT , RSORT ! 23040: # JSR SORTA CALL TO SORT ARRAY ! 23041: # (XR) SORTED ARRAY ! 23042: # (XL,WA,WB,WC) DESTROYED ! 23043: #page ! 23044: # ! 23045: # SORTA (CONTINUED) ! 23046: # ! 23047: .data 1 ! 23048: sorta_s: .long 0 ! 23049: .text 0 ! 23050: sorta: movl (sp)+,sorta_s # entry point ! 23051: movl r6,srtsr # sort/rsort indicator ! 23052: movl $4*num01,srtst # default stride of 1 ! 23053: clrl srtof # default zero offset to sort key ! 23054: movl $nulls,srtdf # clear datatype field name ! 23055: movl (sp)+,r$sxr # unstack argument 2 ! 23056: movl (sp)+,r9 # get first argument ! 23057: jsb gtarr # convert to array ! 23058: .long srt16 # fail ! 23059: movl r9,-(sp) # stack ptr to resulting key array ! 23060: movl r9,-(sp) # another copy for copyb ! 23061: jsb copyb # get copy array for sorting into ! 23062: .long invalid$ # cant fail ! 23063: movl r9,-(sp) # stack pointer to sort array ! 23064: movl r$sxr,r9 # get second arg ! 23065: movl 4*1(sp),r10 # get ptr to key array ! 23066: cmpl (r10),$b$vct # jump if arblk ! 23067: bnequ srt02 ! 23068: cmpl r9,$nulls # jump if null second arg ! 23069: beqlu srt01 ! 23070: jsb gtnvr # get vrblk ptr for it ! 23071: .long er_257 # erroneous 2nd arg in sort/rsort of vector ! 23072: movl r9,srtdf # store datatype field name vrblk ! 23073: # ! 23074: # COMPUTE N AND OFFSET TO ITEM A(0) IN VECTOR CASE ! 23075: # ! 23076: srt01: movl $4*vclen,r8 # offset to a(0) ! 23077: movl $4*vcvls,r7 # offset to first item ! 23078: movl 4*vclen(r10),r6 # get block length ! 23079: subl2 $4*vcsi$,r6 # get no. of entries, n (in bytes) ! 23080: jmp srt04 # merge ! 23081: # ! 23082: # HERE FOR ARRAY ! 23083: # ! 23084: srt02: movl 4*ardim(r10),r5 # get possible dimension ! 23085: movl r5,r6 # convert to short integer ! 23086: moval 0[r6],r6 # further convert to baus ! 23087: movl $4*arvls,r7 # offset to first value if one ! 23088: movl $4*arpro,r8 # offset before values if one dim. ! 23089: cmpl 4*arndm(r10),$num01 # jump in fact if one dim. ! 23090: bnequ 0f ! 23091: jmp srt04 ! 23092: 0: ! 23093: cmpl 4*arndm(r10),$num02 # fail unless two dimens ! 23094: beqlu 0f ! 23095: jmp srt16 ! 23096: 0: ! 23097: movl 4*arlb2(r10),r5 # get lower bound 2 as default ! 23098: cmpl r9,$nulls # jump if default second arg ! 23099: beqlu srt03 ! 23100: jsb gtint # convert to integer ! 23101: .long srt17 # fail ! 23102: movl 4*icval(r9),r5 # get actual integer value ! 23103: #page ! 23104: # ! 23105: # SORTA (CONTINUED) ! 23106: # ! 23107: # HERE WITH SORT COLUMN INDEX IN IA IN ARRAY CASE ! 23108: # ! 23109: srt03: subl2 4*arlb2(r10),r5 # subtract low bound ! 23110: bvc 0f ! 23111: jmp srt17 ! 23112: 0: ! 23113: tstl r5 # fail if below low bound ! 23114: bgeq 0f ! 23115: jmp srt17 ! 23116: 0: ! 23117: subl2 4*ardm2(r10),r5 # check against dimension ! 23118: tstl r5 # fail if too large ! 23119: blss 0f ! 23120: jmp srt17 ! 23121: 0: ! 23122: addl2 4*ardm2(r10),r5 # restore value ! 23123: movl r5,r6 # get as small integer ! 23124: moval 0[r6],r6 # offset within row to key ! 23125: movl r6,srtof # keep offset ! 23126: movl 4*ardm2(r10),r5 # second dimension is row length ! 23127: movl r5,r6 # convert to short integer ! 23128: movl r6,r9 # copy row length ! 23129: moval 0[r6],r6 # convert to bytes ! 23130: movl r6,srtst # store as stride ! 23131: movl 4*ardim(r10),r5 # get number of rows ! 23132: movl r5,r6 # as a short integer ! 23133: moval 0[r6],r6 # convert n to baus ! 23134: movl 4*arlen(r10),r8 # offset past array end ! 23135: subl2 r6,r8 # adjust, giving space for n offsets ! 23136: subl2 $4,r8 # point to a(0) ! 23137: movl 4*arofs(r10),r7 # offset to word before first item ! 23138: addl2 $4,r7 # offset to first item ! 23139: # ! 23140: # SEPARATE PRE-PROCESSING FOR ARRAYS AND VECTORS DONE. ! 23141: # TO SIMPLIFY LATER KEY COMPARISONS, REMOVAL OF ANY TRBLK ! 23142: # TRAP BLOCKS FROM ENTRIES IN KEY ARRAY IS EFFECTED. ! 23143: # ! 23144: # (XL) = 1(XS) = POINTER TO KEY ARRAY ! 23145: # (XS) = POINTER TO SORT ARRAY ! 23146: # WA = NUMBER OF ITEMS, N (CONVERTED TO BYTES). ! 23147: # WB = OFFSET TO FIRST ITEM OF ARRAYS. ! 23148: # WC = OFFSET TO A(0) ! 23149: # ! 23150: srt04: cmpl r6,$4*num01 # return if only a single item ! 23151: bgtru 0f ! 23152: jmp srt15 ! 23153: 0: ! 23154: movl r6,srtsn # store number of items (in baus) ! 23155: movl r8,srtso # store offset to a(0) ! 23156: movl 4*arlen(r10),r8 # length of array or vec (=vclen) ! 23157: addl2 r10,r8 # point past end of array or vector ! 23158: movl r7,srtsf # store offset to first row ! 23159: addl2 r7,r10 # point to first item in key array ! 23160: # ! 23161: # LOOP THROUGH ARRAY ! 23162: # ! 23163: srt05: movl (r10),r9 # get an entry ! 23164: # ! 23165: # HUNT ALONG TRBLK CHAIN ! 23166: # ! 23167: srt06: cmpl (r9),$b$trt # jump out if not trblk ! 23168: bnequ srt07 ! 23169: movl 4*trval(r9),r9 # get value field ! 23170: jmp srt06 # loop ! 23171: #page ! 23172: # ! 23173: # SORTA (CONTINUED) ! 23174: # ! 23175: # XR IS VALUE FROM END OF CHAIN ! 23176: # ! 23177: srt07: movl r9,(r10)+ # store as array entry ! 23178: cmpl r10,r8 # loop if not done ! 23179: blssu srt05 ! 23180: movl (sp),r10 # get adrs of sort array ! 23181: movl srtsf,r9 # initial offset to first key ! 23182: movl srtst,r7 # get stride ! 23183: addl2 srtso,r10 # offset to a(0) ! 23184: addl2 $4,r10 # point to a(1) ! 23185: movl srtsn,r8 # get n ! 23186: ashl $-2,r8,r8 # convert from bytes ! 23187: movl r8,srtnr # store as row count ! 23188: # loop counter ! 23189: # ! 23190: # STORE KEY OFFSETS AT TOP OF SORT ARRAY ! 23191: # ! 23192: srt08: movl r9,(r10)+ # store an offset ! 23193: addl2 r7,r9 # bump offset by stride ! 23194: sobgtr r8,srt08 # loop through rows ! 23195: # ! 23196: # PERFORM THE SORT ON OFFSETS IN SORT ARRAY. ! 23197: # ! 23198: # (SRTSN) NUMBER OF ITEMS TO SORT, N (BYTES) ! 23199: # (SRTSO) OFFSET TO A(0) ! 23200: # ! 23201: srt09: movl srtsn,r6 # get n ! 23202: movl srtnr,r8 # get number of rows ! 23203: ashl $-1,r8,r8 # i = n / 2 (wc=i, index into array) ! 23204: moval 0[r8],r8 # convert back to bytes ! 23205: # ! 23206: # LOOP TO FORM INITIAL HEAP ! 23207: # ! 23208: srt10: jsb sorth # sorth(i,n) ! 23209: subl2 $4,r8 # i = i - 1 ! 23210: tstl r8 # loop if i gt 0 ! 23211: bnequ srt10 ! 23212: movl r6,r8 # i = n ! 23213: # ! 23214: # SORTING LOOP. AT THIS POINT, A(1) IS THE LARGEST ! 23215: # ITEM, SINCE ALGORITHM INITIALISES IT AS, AND THEN MAINTAI ! 23216: # IT AS, ROOT OF TREE. ! 23217: # ! 23218: srt11: subl2 $4,r8 # i = i - 1 (n - 1 initially) ! 23219: tstl r8 # jump if done ! 23220: beqlu srt12 ! 23221: movl (sp),r9 # get sort array address ! 23222: addl2 srtso,r9 # point to a(0) ! 23223: movl r9,r10 # a(0) address ! 23224: addl2 r8,r10 # a(i) address ! 23225: movl 4*1(r10),r7 # copy a(i+1) ! 23226: movl 4*1(r9),4*1(r10)# move a(1) to a(i+1) ! 23227: movl r7,4*1(r9) # complete exchange of a(1), a(i+1) ! 23228: movl r8,r6 # n = i for sorth ! 23229: movl $4*num01,r8 # i = 1 for sorth ! 23230: jsb sorth # sorth(1,n) ! 23231: movl r6,r8 # restore wc ! 23232: jmp srt11 # loop ! 23233: #page ! 23234: # ! 23235: # SORTA (CONTINUED) ! 23236: # ! 23237: # OFFSETS HAVE BEEN PERMUTED INTO REQUIRED ORDER BY SORT. ! 23238: # COPY ARRAY ELEMENTS OVER THEM. ! 23239: # ! 23240: srt12: movl (sp),r10 # base adrs of key array ! 23241: movl r10,r8 # copy it ! 23242: addl2 srtso,r8 # offset of a(0) ! 23243: addl2 srtsf,r10 # adrs of first row of sort array ! 23244: movl srtst,r7 # get stride ! 23245: ashl $-2,r7,r7 # convert to words ! 23246: # ! 23247: # COPYING LOOP FOR SUCCESSIVE ITEMS. SORTED OFFSETS ARE ! 23248: # HELD AT END OF SORT ARRAY. ! 23249: # ! 23250: srt13: addl2 $4,r8 # adrs of next of sorted offsets ! 23251: movl r8,r9 # copy it for access ! 23252: movl (r9),r9 # get offset ! 23253: addl2 4*1(sp),r9 # add key array base adrs ! 23254: movl r7,r6 # get count of words in row ! 23255: # ! 23256: # COPY A COMPLETE ROW ! 23257: # ! 23258: srt14: movl (r9)+,(r10)+ # move a word ! 23259: sobgtr r6,srt14 # loop ! 23260: decl srtnr # decrement row count ! 23261: tstl srtnr # repeat till all rows done ! 23262: bnequ srt13 ! 23263: # ! 23264: # RETURN POINT ! 23265: # ! 23266: srt15: movl (sp)+,r9 # pop result array ptr ! 23267: addl2 $4,sp # pop key array ptr ! 23268: clrl r$sxl # clear junk ! 23269: clrl r$sxr # clear junk ! 23270: jmp *sorta_s # return ! 23271: # ! 23272: # ERROR POINT ! 23273: # ! 23274: srt16: jmp er_256 # sort/rsort 1st arg not suitable array or table ! 23275: srt17: jmp er_258 # sort/rsort 2nd arg out of range or non-integer ! 23276: #enp # end procudure sorta ! 23277: #page ! 23278: # ! 23279: # SORTC -- COMPARE SORT KEYS ! 23280: # ! 23281: # COMPARE TWO SORT KEYS GIVEN THEIR OFFSETS. IF ! 23282: # EQUAL, COMPARE KEY OFFSETS TO GIVE STABLE SORT. ! 23283: # NOTE THAT IF SRTSR IS NON-ZERO (REQUEST FOR REVERSE ! 23284: # SORT), THE QUOTED RETURNS ARE INVERTED. ! 23285: # FOR OBJECTS OF DIFFERING DATATYPES, THE ENTRY POINT ! 23286: # IDENTIFICATIONS ARE COMPARED. ! 23287: # ! 23288: # (XL) BASE ADRS FOR KEYS ! 23289: # (WA) OFFSET TO KEY 1 ITEM ! 23290: # (WB) OFFSET TO KEY 2 ITEM ! 23291: # (SRTSR) ZERO/NON-ZERO FOR SORT/RSORT ! 23292: # (SRTOF) OFFSET WITHIN ROW TO COMPARANDS ! 23293: # JSR SORTC CALL TO COMPARE KEYS ! 23294: # PPM LOC KEY1 LESS THAN KEY2 ! 23295: # NORMAL RETURN, KEY1 GT THAN KEY2 ! 23296: # (XL,XR,WA,WB) DESTROYED ! 23297: # ! 23298: sortc: #prc # entry point ! 23299: movl r6,srts1 # save offset 1 ! 23300: movl r7,srts2 # save offset 2 ! 23301: movl r8,srtsc # save wc ! 23302: addl2 srtof,r10 # add offset to comparand field ! 23303: movl r10,r9 # copy base + offset ! 23304: addl2 r6,r10 # add key1 offset ! 23305: addl2 r7,r9 # add key2 offset ! 23306: movl (r10),r10 # get key1 ! 23307: movl (r9),r9 # get key2 ! 23308: cmpl srtdf,$nulls # jump if datatype field name used ! 23309: beqlu 0f ! 23310: jmp src11 ! 23311: 0: ! 23312: #page ! 23313: # ! 23314: # SORTC (CONTINUED) ! 23315: # ! 23316: # MERGE AFTER DEALING WITH FIELD NAME. TRY FOR STRINGS. ! 23317: # ! 23318: src01: movl (r10),r8 # get type code ! 23319: cmpl r8,(r9) # skip if not same datatype ! 23320: bnequ src02 ! 23321: cmpl r8,$b$scl # jump if both strings ! 23322: beqlu src09 ! 23323: # ! 23324: # NOW TRY FOR NUMERIC ! 23325: # ! 23326: src02: movl r10,r$sxl # keep arg1 ! 23327: movl r9,r$sxr # keep arg2 ! 23328: movl r10,-(sp) # stack ! 23329: movl r9,-(sp) # args ! 23330: jsb acomp # compare objects ! 23331: .long src10 # not numeric ! 23332: .long src10 # not numeric ! 23333: .long src03 # key1 less ! 23334: .long src08 # keys equal ! 23335: .long src05 # key1 greater ! 23336: # ! 23337: # RETURN IF KEY1 SMALLER (SORT), GREATER (RSORT) ! 23338: # ! 23339: src03: tstl srtsr # jump if rsort ! 23340: bnequ src06 ! 23341: # ! 23342: src04: movl srtsc,r8 # restore wc ! 23343: movl (sp)+,r11 # return ! 23344: jmp *(r11)+ ! 23345: # ! 23346: # RETURN IF KEY1 GREATER (SORT), SMALLER (RSORT) ! 23347: # ! 23348: src05: tstl srtsr # jump if rsort ! 23349: bnequ src04 ! 23350: # ! 23351: src06: movl srtsc,r8 # restore wc ! 23352: addl2 $4*1,(sp) # return ! 23353: rsb ! 23354: # ! 23355: # KEYS ARE OF SAME DATATYPE ! 23356: # ! 23357: src07: cmpl r10,r9 # item first created is less ! 23358: blssu src03 ! 23359: cmpl r10,r9 # addresses rise in order of creation ! 23360: bgtru src05 ! 23361: # ! 23362: # DROP THROUGH OR MERGE FOR IDENTICAL OR EQUAL OBJECTS ! 23363: # ! 23364: src08: cmpl srts1,srts2 # test offsets or key addrss instead ! 23365: blssu src04 ! 23366: jmp src06 # offset 1 greater ! 23367: #page ! 23368: # ! 23369: # SORTC (CONTINUED) ! 23370: # ! 23371: # STRINGS ! 23372: # ! 23373: src09: movl r10,-(sp) # stack ! 23374: movl r9,-(sp) # args ! 23375: jsb lcomp # compare objects ! 23376: .long invalid$ # cant ! 23377: .long invalid$ # fail ! 23378: .long src03 # key1 less ! 23379: .long src08 # keys equal ! 23380: .long src05 # key1 greater ! 23381: # ! 23382: # ARITHMETIC COMPARISON FAILED - RECOVER ARGS ! 23383: # ! 23384: src10: movl r$sxl,r10 # get arg1 ! 23385: movl r$sxr,r9 # get arg2 ! 23386: movl (r10),r8 # get type of key1 ! 23387: cmpl r8,(r9) # jump if keys of same type ! 23388: beqlu src07 ! 23389: movl r8,r10 # get block type word ! 23390: movl (r9),r9 # get block type word ! 23391: movzwl -2(r10),r10 # entry point id for key1 ! 23392: movzwl -2(r9),r9 # entry point id for key2 ! 23393: cmpl r10,r9 # jump if key1 gt key2 ! 23394: bgtru src05 ! 23395: jmp src03 # key1 lt key2 ! 23396: # ! 23397: # DATATYPE FIELD NAME USED ! 23398: # ! 23399: src11: jsb sortf # call routine to find field 1 ! 23400: movl r10,-(sp) # stack item pointer ! 23401: movl r9,r10 # get key2 ! 23402: jsb sortf # find field 2 ! 23403: movl r10,r9 # place as key2 ! 23404: movl (sp)+,r10 # recover key1 ! 23405: jmp src01 # merge ! 23406: #enp # procedure sortc ! 23407: #page ! 23408: # ! 23409: # SORTF -- FIND FIELD FOR SORTC ! 23410: # ! 23411: # ROUTINE USED BY SORTC TO OBTAIN ITEM CORRESPONDING ! 23412: # TO A GIVEN FIELD NAME, IF THIS EXISTS, IN A PROGRAMMER ! 23413: # DEFINED OBJECT PASSED AS ARGUMENT. ! 23414: # IF SUCH A MATCH OCCURS, RECORD IS KEPT OF DATATYPE ! 23415: # NAME, FIELD NAME AND OFFSET TO FIELD IN ORDER TO ! 23416: # SHORT-CIRCUIT LATER SEARCHES ON SAME TYPE. NOTE THAT ! 23417: # DFBLKS ARE STORED IN STATIC AND HENCE CANNOT BE MOVED. ! 23418: # ! 23419: # (SRTDF) VRBLK POINTER OF FIELD NAME ! 23420: # (XL) POSSIBLE PDBLK POINTER ! 23421: # JSR SORTF CALL TO SEARCH FOR FIELD NAME ! 23422: # (XL) ITEM FOUND OR ORIGINAL PDBLK PTR ! 23423: # (WC) DESTROYED ! 23424: # ! 23425: sortf: #prc # entry point ! 23426: cmpl (r10),$b$pdt # return if not pdblk ! 23427: bnequ srtf3 ! 23428: movl r9,-(sp) # keep xr ! 23429: movl srtfd,r9 # get possible former dfblk ptr ! 23430: tstl r9 # jump if not ! 23431: beqlu srtf4 ! 23432: cmpl r9,4*pddfp(r10) # jump if not right datatype ! 23433: bnequ srtf4 ! 23434: cmpl srtdf,srtff # jump if not right field name ! 23435: bnequ srtf4 ! 23436: addl2 srtfo,r10 # add offset to required field ! 23437: # ! 23438: # HERE WITH XL POINTING TO FOUND FIELD ! 23439: # ! 23440: srtf1: movl (r10),r10 # get item from field ! 23441: # ! 23442: # RETURN POINT ! 23443: # ! 23444: srtf2: movl (sp)+,r9 # restore xr ! 23445: # ! 23446: srtf3: rsb # return ! 23447: #page ! 23448: # ! 23449: # SORTF (CONTINUED) ! 23450: # ! 23451: # CONDUCT A SEARCH ! 23452: # ! 23453: srtf4: movl r10,r9 # copy original pointer ! 23454: movl 4*pddfp(r9),r9 # point to dfblk ! 23455: movl r9,srtfd # keep a copy ! 23456: movl 4*fargs(r9),r8 # get number of fields ! 23457: moval 0[r8],r8 # convert to bytes ! 23458: addl2 4*dflen(r9),r9 # point past last field ! 23459: # ! 23460: # LOOP TO FIND NAME IN PDFBLK ! 23461: # ! 23462: srtf5: subl2 $4,r8 # count down ! 23463: subl2 $4,r9 # point in front ! 23464: cmpl (r9),srtdf # skip out if found ! 23465: beqlu srtf6 ! 23466: tstl r8 # loop ! 23467: bnequ srtf5 ! 23468: jmp srtf2 # return - not found ! 23469: # ! 23470: # FOUND ! 23471: # ! 23472: srtf6: movl (r9),srtff # keep field name ptr ! 23473: addl2 $4*pdfld,r8 # add offset to first field ! 23474: movl r8,srtfo # store as field offset ! 23475: addl2 r8,r10 # point to field ! 23476: jmp srtf1 # return ! 23477: #enp # procedure sortf ! 23478: #page ! 23479: # ! 23480: # SORTH -- HEAP ROUTINE FOR SORTA ! 23481: # ! 23482: # THIS ROUTINE CONSTRUCTS A HEAP FROM ELEMENTS OF ARRAY, A. ! 23483: # IN THIS APPLICATION, THE ELEMENTS ARE OFFSETS TO KEYS IN ! 23484: # A KEY ARRAY. ! 23485: # ! 23486: # (XS) POINTER TO SORT ARRAY BASE ! 23487: # 1(XS) POINTER TO KEY ARRAY BASE ! 23488: # (WA) MAX ARRAY INDEX, N (IN BYTES) ! 23489: # (WC) OFFSET J IN A TO ROOT (IN *1 TO *N) ! 23490: # JSR SORTH CALL SORTH(J,N) TO MAKE HEAP ! 23491: # (XL,XR,WB) DESTROYED ! 23492: # ! 23493: .data 1 ! 23494: sorth_s: .long 0 ! 23495: .text 0 ! 23496: sorth: movl (sp)+,sorth_s # entry point ! 23497: movl r6,srtsn # save n ! 23498: movl r8,srtwc # keep wc ! 23499: movl (sp),r10 # sort array base adrs ! 23500: addl2 srtso,r10 # add offset to a(0) ! 23501: addl2 r8,r10 # point to a(j) ! 23502: movl (r10),srtrt # get offset to root ! 23503: addl2 r8,r8 # double j - cant exceed n ! 23504: # ! 23505: # LOOP TO MOVE DOWN TREE USING DOUBLED INDEX J ! 23506: # ! 23507: srh01: cmpl r8,srtsn # done if j gt n ! 23508: bgtru srh03 ! 23509: cmpl r8,srtsn # skip if j equals n ! 23510: beqlu srh02 ! 23511: movl (sp),r9 # sort array base adrs ! 23512: movl 4*1(sp),r10 # key array base adrs ! 23513: addl2 srtso,r9 # point to a(0) ! 23514: addl2 r8,r9 # adrs of a(j) ! 23515: movl 4*1(r9),r6 # get a(j+1) ! 23516: movl (r9),r7 # get a(j) ! 23517: # ! 23518: # COMPARE SONS. (WA) RIGHT SON, (WB) LEFT SON ! 23519: # ! 23520: jsb sortc # compare keys - lt(a(j+1),a(j)) ! 23521: .long srh02 # a(j+1) lt a(j) ! 23522: addl2 $4,r8 # point to greater son, a(j+1) ! 23523: #page ! 23524: # ! 23525: # SORTH (CONTINUED) ! 23526: # ! 23527: # COMPARE ROOT WITH GREATER SON ! 23528: # ! 23529: srh02: movl 4*1(sp),r10 # key array base adrs ! 23530: movl (sp),r9 # get sort array address ! 23531: addl2 srtso,r9 # adrs of a(0) ! 23532: movl r9,r7 # copy this adrs ! 23533: addl2 r8,r9 # adrs of greater son, a(j) ! 23534: movl (r9),r6 # get a(j) ! 23535: movl r7,r9 # point back to a(0) ! 23536: movl srtrt,r7 # get root ! 23537: jsb sortc # compare them - lt(a(j),root) ! 23538: .long srh03 # father exceeds sons - done ! 23539: movl (sp),r9 # get sort array adrs ! 23540: addl2 srtso,r9 # point to a(0) ! 23541: movl r9,r10 # copy it ! 23542: movl r8,r6 # copy j ! 23543: ashl $-2,r8,r8 # convert to words ! 23544: ashl $-1,r8,r8 # get j/2 ! 23545: moval 0[r8],r8 # convert back to bytes ! 23546: addl2 r6,r10 # point to a(j) ! 23547: addl2 r8,r9 # adrs of a(j/2) ! 23548: movl (r10),(r9) # a(j/2) = a(j) ! 23549: movl r6,r8 # recover j ! 23550: addl2 r8,r8 # j = j*2. done if too big ! 23551: bvc 0f ! 23552: jmp srh03 ! 23553: 0: ! 23554: jmp srh01 # loop ! 23555: # ! 23556: # FINISH BY COPYING ROOT OFFSET BACK INTO ARRAY ! 23557: # ! 23558: srh03: ashl $-2,r8,r8 # convert to words ! 23559: ashl $-1,r8,r8 # j = j/2 ! 23560: moval 0[r8],r8 # convert back to bytes ! 23561: movl (sp),r9 # sort array adrs ! 23562: addl2 srtso,r9 # adrs of a(0) ! 23563: addl2 r8,r9 # adrs of a(j/2) ! 23564: movl srtrt,(r9) # a(j/2) = root ! 23565: movl srtsn,r6 # restore wa ! 23566: movl srtwc,r8 # restore wc ! 23567: jmp *sorth_s # return ! 23568: #enp # end procedure sorth ! 23569: #page ! 23570: #page ! 23571: # ! 23572: # TFIND -- LOCATE TABLE ELEMENT ! 23573: # ! 23574: # (XR) SUBSCRIPT VALUE FOR ELEMENT ! 23575: # (XL) POINTER TO TABLE ! 23576: # (WB) ZERO BY VALUE, NON-ZERO BY NAME ! 23577: # JSR TFIND CALL TO LOCATE ELEMENT ! 23578: # PPM LOC TRANSFER LOCATION IF ACCESS FAILS ! 23579: # (XR) ELEMENT VALUE (IF BY VALUE) ! 23580: # (XR) DESTROYED (IF BY NAME) ! 23581: # (XL,WA) TEBLK NAME (IF BY NAME) ! 23582: # (XL,WA) DESTROYED (IF BY VALUE) ! 23583: # (WC,RA) DESTROYED ! 23584: # ! 23585: # NOTE THAT IF A CALL BY VALUE SPECIFIES A NON-EXISTENT ! 23586: # SUBSCRIPT, NULL IS RETURNED WITHOUT BUILDING A NEW TEBLK. ! 23587: # ! 23588: tfind: #prc # entry point ! 23589: movl r7,-(sp) # save name/value indicator ! 23590: movl r9,-(sp) # save subscript value ! 23591: movl r10,-(sp) # save table pointer ! 23592: movl 4*tblen(r10),r6 # load length of tbblk ! 23593: ashl $-2,r6,r6 # convert to word count ! 23594: subl2 $tbbuk,r6 # get number of buckets ! 23595: movl r6,r5 # convert to integer value ! 23596: movl r5,tfnsi # save for later ! 23597: movl (r9),r10 # load first word of subscript ! 23598: movzwl -2(r10),r10 # load block entry id (bl$xx) ! 23599: casel r10,$0,$bl$$d # switch on block type ! 23600: 5: ! 23601: .word tfn00-5b ! 23602: .word tfn00-5b ! 23603: .word tfn00-5b ! 23604: .word tfn00-5b ! 23605: .word tfn02-5b # jump if integer ! 23606: .word tfn04-5b # jump if name ! 23607: .word tfn03-5b # jump if pattern ! 23608: .word tfn03-5b # jump if pattern ! 23609: .word tfn03-5b # jump if pattern ! 23610: .word tfn02-5b # real ! 23611: .word tfn05-5b # jump if string ! 23612: .word tfn00-5b ! 23613: .word tfn00-5b ! 23614: .word tfn00-5b ! 23615: .word tfn00-5b ! 23616: .word tfn00-5b ! 23617: .word tfn00-5b ! 23618: #esw # end switch on block type ! 23619: # ! 23620: # HERE FOR BLOCKS FOR WHICH WE USE THE SECOND WORD OF THE ! 23621: # BLOCK AS THE HASH SOURCE (SEE BLOCK FORMATS FOR DETAILS). ! 23622: # ! 23623: tfn00: movl 4*1(r9),r6 # load second word ! 23624: # ! 23625: # MERGE HERE WITH ONE WORD HASH SOURCE IN WA ! 23626: # ! 23627: tfn01: movl r6,r5 # convert to integer ! 23628: jmp tfn06 # jump to merge ! 23629: #page ! 23630: # ! 23631: # TFIND (CONTINUED) ! 23632: # ! 23633: # HERE FOR INTEGER OR REAL ! 23634: # ! 23635: tfn02: movl 4*1(r9),r5 # load value as hash source ! 23636: tstl r5 # ok if positive or zero ! 23637: bgeq tfn06 ! 23638: mnegl r5,r5 # make positive ! 23639: bvs tfn06 ! 23640: jmp tfn06 # merge ! 23641: # ! 23642: # FOR PATTERN, USE FIRST WORD (PCODE) AS SOURCE ! 23643: # ! 23644: tfn03: movl (r9),r6 # load first word as hash source ! 23645: jmp tfn01 # merge back ! 23646: # ! 23647: # FOR NAME, USE OFFSET AS HASH SOURCE ! 23648: # ! 23649: tfn04: movl 4*nmofs(r9),r6 # load offset as hash source ! 23650: jmp tfn01 # merge back ! 23651: # ! 23652: # HERE FOR STRING ! 23653: # ! 23654: tfn05: jsb hashs # call routine to compute hash ! 23655: # ! 23656: # MERGE HERE WITH HASH SOURCE IN (IA) ! 23657: # ! 23658: tfn06: ashq $-32,r4,r4 # compute hash index by remaindering ! 23659: ediv tfnsi,r4,r11,r5 ! 23660: movl r5,r8 # get as one word integer ! 23661: moval 0[r8],r8 # convert to byte offset ! 23662: movl (sp),r10 # get table ptr again ! 23663: addl2 r8,r10 # point to proper bucket ! 23664: movl 4*tbbuk(r10),r9 # load first teblk pointer ! 23665: cmpl r9,(sp) # jump if no teblks on chain ! 23666: beqlu tfn10 ! 23667: # ! 23668: # LOOP THROUGH TEBLKS ON HASH CHAIN ! 23669: # ! 23670: tfn07: movl r9,r7 # save teblk pointer ! 23671: movl 4*tesub(r9),r9 # load subscript value ! 23672: movl 4*1(sp),r10 # load input argument subscript val ! 23673: jsb ident # compare them ! 23674: .long tfn08 # jump if equal (ident) ! 23675: # ! 23676: # HERE IF NO MATCH WITH THAT TEBLK ! 23677: # ! 23678: movl r7,r10 # restore teblk pointer ! 23679: movl 4*tenxt(r10),r9 # point to next teblk on chain ! 23680: cmpl r9,(sp) # jump if there is one ! 23681: bnequ tfn07 ! 23682: # ! 23683: # HERE IF NO MATCH WITH ANY TEBLK ON CHAIN ! 23684: # ! 23685: movl $4*tenxt,r8 # set offset to link field (xl base) ! 23686: jmp tfn11 # jump to merge ! 23687: #page ! 23688: # ! 23689: # TFIND (CONTINUED) ! 23690: # ! 23691: # HERE WE HAVE FOUND A MATCHING ELEMENT ! 23692: # ! 23693: tfn08: movl r7,r10 # restore teblk pointer ! 23694: movl $4*teval,r6 # set teblk name offset ! 23695: movl 4*2(sp),r7 # restore name/value indicator ! 23696: tstl r7 # jump if called by name ! 23697: bnequ tfn09 ! 23698: jsb acess # else get value ! 23699: .long tfn12 # jump if reference fails ! 23700: clrl r7 # restore name/value indicator ! 23701: # ! 23702: # COMMON EXIT FOR ENTRY FOUND ! 23703: # ! 23704: tfn09: addl2 $4*num03,sp # pop stack entries ! 23705: addl2 $4*1,(sp) # return to tfind caller ! 23706: rsb ! 23707: # ! 23708: # HERE IF NO TEBLKS ON THE HASH CHAIN ! 23709: # ! 23710: tfn10: addl2 $4*tbbuk,r8 # get offset to bucket ptr ! 23711: movl (sp),r10 # set tbblk ptr as base ! 23712: # ! 23713: # MERGE HERE WITH (XL,WC) BASE,OFFSET OF FINAL LINK ! 23714: # ! 23715: tfn11: movl (sp),r9 # tbblk pointer ! 23716: movl 4*tbinv(r9),r9 # load default value in case ! 23717: movl 4*2(sp),r7 # load name/value indicator ! 23718: tstl r7 # exit with default if value call ! 23719: beqlu tfn09 ! 23720: # ! 23721: # HERE WE MUST BUILD A NEW TEBLK ! 23722: # ! 23723: movl $4*tesi$,r6 # set size of teblk ! 23724: jsb alloc # allocate teblk ! 23725: addl2 r8,r10 # point to hash link ! 23726: movl r9,(r10) # link new teblk at end of chain ! 23727: movl $b$tet,(r9) # store type word ! 23728: movl $nulls,4*teval(r9) # set null as initial value ! 23729: movl (sp)+,4*tenxt(r9)# set tbblk ptr to mark end of chain ! 23730: movl (sp)+,4*tesub(r9)# store subscript value ! 23731: addl2 $4,sp # pop past name/value indicator ! 23732: movl r9,r10 # copy teblk pointer (name base) ! 23733: movl $4*teval,r6 # set offset ! 23734: addl2 $4*1,(sp) # return to caller with new teblk ! 23735: rsb ! 23736: # ! 23737: # ACESS FAIL RETURN ! 23738: # ! 23739: tfn12: movl (sp)+,r11 # alternative return ! 23740: jmp *(r11)+ ! 23741: #enp # end procedure tfind ! 23742: #page ! 23743: # ! 23744: # TRACE -- SET/RESET A TRACE ASSOCIATION ! 23745: # ! 23746: # THIS PROCEDURE IS SHARED BY TRACE AND STOPTR TO ! 23747: # EITHER INITIATE OR STOP A TRACE RESPECTIVELY. ! 23748: # ! 23749: # (XL) TRBLK PTR (TRACE) OR ZERO (STOPTR) ! 23750: # 1(XS) FIRST ARGUMENT (NAME) ! 23751: # 0(XS) SECOND ARGUMENT (TRACE TYPE) ! 23752: # JSR TRACE CALL TO SET/RESET TRACE ! 23753: # PPM LOC TRANSFER LOC IF 1ST ARG IS BAD NAME ! 23754: # PPM LOC TRANSFER LOC IF 2ND ARG IS BAD TYPE ! 23755: # (XS) POPPED ! 23756: # (XL,XR,WA,WB,WC,IA) DESTROYED ! 23757: # ! 23758: .data 1 ! 23759: trace_s: .long 0 ! 23760: .text 0 ! 23761: trace: movl (sp)+,trace_s # entry point ! 23762: jsb gtstg # get trace type string ! 23763: .long trc15 # jump if not string ! 23764: movab cfp$f(r9),r9 # else point to string ! 23765: movzbl (r9),r6 # load first character ! 23766: bicl2 $ch$bl,r6 # fold to upper case ! 23767: movl (sp),r9 # load name argument ! 23768: movl r10,(sp) # stack trblk ptr or zero ! 23769: movl $trtac,r8 # set trtyp for access trace ! 23770: cmpl r6,$ch$la # jump if a (access) ! 23771: bnequ 0f ! 23772: jmp trc10 ! 23773: 0: ! 23774: movl $trtvl,r8 # set trtyp for value trace ! 23775: cmpl r6,$ch$lv # jump if v (value) ! 23776: bnequ 0f ! 23777: jmp trc10 ! 23778: 0: ! 23779: tstl r6 # jump if blank (value) ! 23780: bnequ 0f ! 23781: jmp trc10 ! 23782: 0: ! 23783: # ! 23784: # HERE FOR L,K,F,C,R ! 23785: # ! 23786: cmpl r6,$ch$lf # jump if f (function) ! 23787: beqlu trc01 ! 23788: cmpl r6,$ch$lr # jump if r (return) ! 23789: beqlu trc01 ! 23790: cmpl r6,$ch$ll # jump if l (label) ! 23791: beqlu trc03 ! 23792: cmpl r6,$ch$lk # jump if k (keyword) ! 23793: bnequ 0f ! 23794: jmp trc06 ! 23795: 0: ! 23796: cmpl r6,$ch$lc # else error if not c (call) ! 23797: beqlu 0f ! 23798: jmp trc15 ! 23799: 0: ! 23800: # ! 23801: # HERE FOR F,C,R ! 23802: # ! 23803: trc01: jsb gtnvr # point to vrblk for name ! 23804: .long trc16 # jump if bad name ! 23805: addl2 $4,sp # pop stack ! 23806: movl 4*vrfnc(r9),r9 # point to function block ! 23807: cmpl (r9),$b$pfc # error if not program function ! 23808: beqlu 0f ! 23809: jmp trc17 ! 23810: 0: ! 23811: cmpl r6,$ch$lr # jump if r (return) ! 23812: beqlu trc02 ! 23813: #page ! 23814: # ! 23815: # TRACE (CONTINUED) ! 23816: # ! 23817: # HERE FOR F,C TO SET/RESET CALL TRACE ! 23818: # ! 23819: movl r10,4*pfctr(r9) # set/reset call trace ! 23820: cmpl r6,$ch$lc # exit with null if c (call) ! 23821: bnequ 0f ! 23822: jmp exnul ! 23823: 0: ! 23824: # ! 23825: # HERE FOR F,R TO SET/RESET RETURN TRACE ! 23826: # ! 23827: trc02: movl r10,4*pfrtr(r9) # set/reset return trace ! 23828: addl3 $4*2,trace_s,r11 # return ! 23829: jmp (r11) ! 23830: # ! 23831: # HERE FOR L TO SET/RESET LABEL TRACE ! 23832: # ! 23833: trc03: jsb gtnvr # point to vrblk ! 23834: .long trc16 # jump if bad name ! 23835: movl 4*vrlbl(r9),r10 # load label pointer ! 23836: cmpl (r10),$b$trt # jump if no old trace ! 23837: bnequ trc04 ! 23838: movl 4*trlbl(r10),r10# else delete old trace association ! 23839: # ! 23840: # HERE WITH OLD LABEL TRACE ASSOCIATION DELETED ! 23841: # ! 23842: trc04: cmpl r10,$stndl # error if undefined label ! 23843: bnequ 0f ! 23844: jmp trc16 ! 23845: 0: ! 23846: movl (sp)+,r7 # get trblk ptr again ! 23847: tstl r7 # jump if stoptr case ! 23848: beqlu trc05 ! 23849: movl r7,4*vrlbl(r9) # else set new trblk pointer ! 23850: movl $b$vrt,4*vrtra(r9) # set label trace routine address ! 23851: movl r7,r9 # copy trblk pointer ! 23852: movl r10,4*trlbl(r9) # store real label in trblk ! 23853: addl3 $4*2,trace_s,r11 # return ! 23854: jmp (r11) ! 23855: # ! 23856: # HERE FOR STOPTR CASE FOR LABEL ! 23857: # ! 23858: trc05: movl r10,4*vrlbl(r9) # store label ptr back in vrblk ! 23859: movl $b$vrg,4*vrtra(r9) # store normal transfer address ! 23860: addl3 $4*2,trace_s,r11 # return ! 23861: jmp (r11) ! 23862: #page ! 23863: # ! 23864: # TRACE (CONTINUED) ! 23865: # ! 23866: # HERE FOR K (KEYWORD) ! 23867: # ! 23868: trc06: jsb gtnvr # point to vrblk ! 23869: .long trc16 # error if not natural var ! 23870: tstl 4*vrlen(r9) # error if not system var ! 23871: beqlu 0f ! 23872: jmp trc16 ! 23873: 0: ! 23874: addl2 $4,sp # pop stack ! 23875: tstl r10 # jump if stoptr case ! 23876: beqlu trc07 ! 23877: movl r9,4*trkvr(r10) # store vrblk ptr in trblk for ktrex ! 23878: # ! 23879: # MERGE HERE WITH TRBLK SET UP IN WB (OR ZERO) ! 23880: # ! 23881: trc07: movl 4*vrsvp(r9),r9 # point to svblk ! 23882: cmpl r9,$v$ert # jump if errtype ! 23883: beqlu trc08 ! 23884: cmpl r9,$v$stc # jump if stcount ! 23885: beqlu trc09 ! 23886: cmpl r9,$v$fnc # else error if not fnclevel ! 23887: beqlu 0f ! 23888: jmp trc17 ! 23889: 0: ! 23890: # ! 23891: # FNCLEVEL ! 23892: # ! 23893: movl r10,r$fnc # set/reset fnclevel trace ! 23894: addl3 $4*2,trace_s,r11 # return ! 23895: jmp (r11) ! 23896: # ! 23897: # ERRTYPE ! 23898: # ! 23899: trc08: movl r10,r$ert # set/reset errtype trace ! 23900: addl3 $4*2,trace_s,r11 # return ! 23901: jmp (r11) ! 23902: # ! 23903: # STCOUNT ! 23904: # ! 23905: trc09: movl r10,r$stc # set/reset stcount trace ! 23906: addl3 $4*2,trace_s,r11 # return ! 23907: jmp (r11) ! 23908: #page ! 23909: # ! 23910: # TRACE (CONTINUED) ! 23911: # ! 23912: # A,V MERGE HERE WITH TRTYP VALUE IN WC ! 23913: # ! 23914: trc10: jsb gtvar # locate variable ! 23915: .long trc16 # error if not appropriate name ! 23916: movl (sp)+,r7 # get new trblk ptr again ! 23917: addl2 r10,r6 # point to variable location ! 23918: movl r6,r9 # copy variable pointer ! 23919: # ! 23920: # LOOP TO SEARCH TRBLK CHAIN ! 23921: # ! 23922: trc11: movl (r9),r10 # point to next entry ! 23923: cmpl (r10),$b$trt # jump if not trblk ! 23924: bnequ trc13 ! 23925: cmpl r8,4*trtyp(r10) # jump if too far out on chain ! 23926: blssu trc13 ! 23927: cmpl r8,4*trtyp(r10) # jump if this matches our type ! 23928: beqlu trc12 ! 23929: addl2 $4*trnxt,r10 # else point to link field ! 23930: movl r10,r9 # copy pointer ! 23931: jmp trc11 # and loop back ! 23932: # ! 23933: # HERE TO DELETE AN OLD TRBLK OF THE TYPE WE WERE GIVEN ! 23934: # ! 23935: trc12: movl 4*trnxt(r10),r10# get ptr to next block or value ! 23936: movl r10,(r9) # store to delete this trblk ! 23937: # ! 23938: # HERE AFTER DELETING ANY OLD ASSOCIATION OF THIS TYPE ! 23939: # ! 23940: trc13: tstl r7 # jump if stoptr case ! 23941: beqlu trc14 ! 23942: movl r7,(r9) # else link new trblk in ! 23943: movl r7,r9 # copy trblk pointer ! 23944: movl r10,4*trnxt(r9) # store forward pointer ! 23945: movl r8,4*trtyp(r9) # store appropriate trap type code ! 23946: # ! 23947: # HERE TO MAKE SURE VRGET,VRSTO ARE SET PROPERLY ! 23948: # ! 23949: trc14: movl r6,r9 # recall possible vrblk pointer ! 23950: subl2 $4*vrval,r9 # point back to vrblk ! 23951: jsb setvr # set fields if vrblk ! 23952: addl3 $4*2,trace_s,r11 # return ! 23953: jmp (r11) ! 23954: # ! 23955: # HERE FOR BAD TRACE TYPE ! 23956: # ! 23957: trc15: addl3 $4*1,trace_s,r11 # take bad trace type error exit ! 23958: jmp *(r11)+ ! 23959: # ! 23960: # POP STACK BEFORE FAILING ! 23961: # ! 23962: trc16: addl2 $4,sp # pop stack ! 23963: # ! 23964: # HERE FOR BAD NAME ARGUMENT ! 23965: # ! 23966: trc17: movl trace_s,r11 # take bad name error exit ! 23967: jmp *(r11)+ ! 23968: #enp # end procedure trace ! 23969: #page ! 23970: # ! 23971: # TRBLD -- BUILD TRBLK ! 23972: # ! 23973: # TRBLK IS USED BY THE INPUT, OUTPUT AND TRACE FUNCTIONS ! 23974: # TO CONSTRUCT A TRBLK (TRAP BLOCK) ! 23975: # ! 23976: # (XR) TRTAG OR TRTER ! 23977: # (XL) TRFNC OR TRFPT ! 23978: # (WB) TRTYP ! 23979: # JSR TRBLD CALL TO BUILD TRBLK ! 23980: # (XR) POINTER TO TRBLK ! 23981: # (WA) DESTROYED ! 23982: # ! 23983: trbld: #prc # entry point ! 23984: movl r9,-(sp) # stack trtag (or trfnm) ! 23985: movl $4*trsi$,r6 # set size of trblk ! 23986: jsb alloc # allocate trblk ! 23987: movl $b$trt,(r9) # store first word ! 23988: movl r10,4*trfnc(r9) # store trfnc (or trfpt) ! 23989: movl (sp)+,4*trtag(r9)# store trtag (or trfnm) ! 23990: movl r7,4*trtyp(r9) # store type ! 23991: movl $nulls,4*trval(r9) # for now, a null value ! 23992: rsb # return to caller ! 23993: #enp # end procedure trbld ! 23994: #page ! 23995: # ! 23996: # TRIMR -- TRIM TRAILING BLANKS ! 23997: # ! 23998: # TRIMR IS PASSED A POINTER TO AN SCBLK WHICH MUST BE THE ! 23999: # LAST BLOCK IN DYNAMIC STORAGE. TRAILING BLANKS ARE ! 24000: # TRIMMED OFF AND THE DYNAMIC STORAGE POINTER RESET TO ! 24001: # THE END OF THE (POSSIBLY) SHORTENED BLOCK. ! 24002: # ! 24003: # (WB) NON-ZERO TO TRIM TRAILING BLANKS ! 24004: # (XR) POINTER TO STRING TO TRIM ! 24005: # JSR TRIMR CALL TO TRIM STRING ! 24006: # (XR) POINTER TO TRIMMED STRING ! 24007: # (XL,WA,WB,WC) DESTROYED ! 24008: # ! 24009: # THE CALL WITH WB ZERO STILL PERFORMS THE END ZERO PAD ! 24010: # AND DNAMP READJUSTMENT. IT IS USED FROM ACESS IF KVTRM=0. ! 24011: # ! 24012: trimr: #prc # entry point ! 24013: movl r9,r10 # copy string pointer ! 24014: movl 4*sclen(r9),r6 # load string length ! 24015: tstl r6 # jump if null input ! 24016: beqlu trim2 ! 24017: movab cfp$f(r10)[r6],r10 # else point past last character ! 24018: tstl r7 # jump if no trim ! 24019: beqlu trim3 ! 24020: movl $ch$bl,r8 # load blank character ! 24021: # ! 24022: # LOOP THROUGH CHARACTERS FROM RIGHT TO LEFT ! 24023: # ! 24024: trim0: movzbl -(r10),r7 # load next character ! 24025: cmpl r7,$ch$ht # jump if horizontal tab ! 24026: beqlu trim1 ! 24027: cmpl r7,r8 # jump if non-blank found ! 24028: bnequ trim3 ! 24029: trim1: decl r6 # else decrement character count ! 24030: tstl r6 # loop back if more to check ! 24031: bnequ trim0 ! 24032: # ! 24033: # HERE IF RESULT IS NULL (NULL OR ALL-BLANK INPUT) ! 24034: # ! 24035: trim2: movl r9,dnamp # wipe out input string block ! 24036: movl $nulls,r9 # load null result ! 24037: jmp trim5 # merge to exit ! 24038: #page ! 24039: # ! 24040: # TRIMR (CONTINUED) ! 24041: # ! 24042: # HERE WITH NON-BLANK FOUND (MERGE FOR NO TRIM) ! 24043: # ! 24044: trim3: movl r6,4*sclen(r9) # set new length ! 24045: movl r9,r10 # copy string pointer ! 24046: movab cfp$f(r10)[r6],r10 # ready for storing blanks ! 24047: movab 3+(4*schar)(r6),r6 # get length of block in bytes ! 24048: bicl2 $3,r6 ! 24049: addl2 r9,r6 # point past new block ! 24050: movl r6,dnamp # set new top of storage pointer ! 24051: movl $cfp$c,r6 # get count of chars in word ! 24052: clrl r8 # set blank char ! 24053: # ! 24054: # LOOP TO ZERO PAD LAST WORD OF CHARACTERS ! 24055: # ! 24056: trim4: movb r8,(r10)+ # store zero character ! 24057: sobgtr r6,trim4 # loop back till all stored ! 24058: #csc r10 # complete store characters ! 24059: # ! 24060: # COMMON EXIT POINT ! 24061: # ! 24062: trim5: clrl r10 # clear garbage xl pointer ! 24063: rsb # return to caller ! 24064: #enp # end procedure trimr ! 24065: #page ! 24066: # ! 24067: # TRXEQ -- EXECUTE FUNCTION TYPE TRACE ! 24068: # ! 24069: # TRXEQ IS USED TO EXECUTE A TRACE WHEN A FOURTH ARGUMENT ! 24070: # HAS BEEN SUPPLIED. TRACE HAS ALREADY BEEN DECREMENTED. ! 24071: # ! 24072: # (XR) POINTER TO TRBLK ! 24073: # (XL,WA) NAME BASE,OFFSET FOR VARIABLE ! 24074: # JSR TRXEQ CALL TO EXECUTE TRACE ! 24075: # (WB,WC,RA) DESTROYED ! 24076: # ! 24077: # THE FOLLOWING STACK ENTRIES ARE MADE BEFORE PASSING ! 24078: # CONTROL TO THE TRACE FUNCTION USING THE CFUNC ROUTINE. ! 24079: # ! 24080: # TRXEQ RETURN POINT WORD(S) ! 24081: # SAVED VALUE OF TRACE KEYWORD ! 24082: # TRBLK POINTER ! 24083: # NAME BASE ! 24084: # NAME OFFSET ! 24085: # SAVED VALUE OF R$COD ! 24086: # SAVED CODE PTR (-R$COD) ! 24087: # SAVED VALUE OF FLPTR ! 24088: # FLPTR --------------- ZERO (DUMMY FAIL OFFSET) ! 24089: # NMBLK FOR VARIABLE NAME ! 24090: # XS ------------------ TRACE TAG ! 24091: # ! 24092: # R$COD AND THE CODE PTR ARE SET TO DUMMY VALUES WHICH ! 24093: # CAUSE CONTROL TO RETURN TO THE TRXEQ PROCEDURE ON SUCCESS ! 24094: # OR FAILURE (TRXEQ IGNORES A FAILURE CONDITION). ! 24095: # ! 24096: trxeq: #prc # entry point (recursive) ! 24097: movl r$cod,r8 # load code block pointer ! 24098: movl r3,r7 # get current code pointer ! 24099: subl2 r8,r7 # make code pointer into offset ! 24100: movl kvtra,-(sp) # stack trace keyword value ! 24101: movl r9,-(sp) # stack trblk pointer ! 24102: movl r10,-(sp) # stack name base ! 24103: movl r6,-(sp) # stack name offset ! 24104: movl r8,-(sp) # stack code block pointer ! 24105: movl r7,-(sp) # stack code pointer offset ! 24106: movl flptr,-(sp) # stack old failure pointer ! 24107: clrl -(sp) # set dummy fail offset ! 24108: movl sp,flptr # set new failure pointer ! 24109: clrl kvtra # reset trace keyword to zero ! 24110: movl $trxdc,r8 # load new (dummy) code blk pointer ! 24111: movl r8,r$cod # set as code block pointer ! 24112: movl r8,r3 # and new code pointer ! 24113: #page ! 24114: # ! 24115: # TRXEQ (CONTINUED) ! 24116: # ! 24117: # NOW PREPARE ARGUMENTS FOR FUNCTION ! 24118: # ! 24119: movl r6,r7 # save name offset ! 24120: movl $4*nmsi$,r6 # load nmblk size ! 24121: jsb alloc # allocate space for nmblk ! 24122: movl $b$nml,(r9) # set type word ! 24123: movl r10,4*nmbas(r9) # store name base ! 24124: movl r7,4*nmofs(r9) # store name offset ! 24125: movl 4*6(sp),r10 # reload pointer to trblk ! 24126: movl r9,-(sp) # stack nmblk pointer (1st argument) ! 24127: movl 4*trtag(r10),-(sp) # stack trace tag (2nd argument) ! 24128: movl 4*trfnc(r10),r10# load trace function pointer ! 24129: movl $num02,r6 # set number of arguments to two ! 24130: jmp cfunc # jump to call function ! 24131: # ! 24132: # SEE O$TXR FOR DETAILS OF RETURN TO THIS POINT ! 24133: # ! 24134: trxq1: movl flptr,sp # point back to our stack entries ! 24135: addl2 $4,sp # pop off garbage fail offset ! 24136: movl (sp)+,flptr # restore old failure pointer ! 24137: movl (sp)+,r7 # reload code offset ! 24138: movl (sp)+,r8 # load old code base pointer ! 24139: movl r8,r9 # copy cdblk pointer ! 24140: movl 4*cdstm(r9),kvstn# restore stmnt no ! 24141: movl (sp)+,r6 # reload name offset ! 24142: movl (sp)+,r10 # reload name base ! 24143: movl (sp)+,r9 # reload trblk pointer ! 24144: movl (sp)+,kvtra # restore trace keyword value ! 24145: addl2 r8,r7 # recompute absolute code pointer ! 24146: movl r7,r3 # restore code pointer ! 24147: movl r8,r$cod # and code block pointer ! 24148: rsb # return to trxeq caller ! 24149: #enp # end procedure trxeq ! 24150: #page ! 24151: # ! 24152: # XSCAN -- EXECUTION FUNCTION ARGUMENT SCAN ! 24153: # ! 24154: # XSCAN SCANS OUT ONE TOKEN IN A PROTOTYPE ARGUMENT IN ! 24155: # ARRAY,CLEAR,DATA,DEFINE,LOAD FUNCTION CALLS. XSCAN ! 24156: # CALLS MUST BE PRECEDED BY A CALL TO THE INITIALIZATION ! 24157: # PROCEDURE XSCNI. THE FOLLOWING VARIABLES ARE USED. ! 24158: # ! 24159: # R$XSC POINTER TO SCBLK FOR FUNCTION ARG ! 24160: # XSOFS OFFSET (NUM CHARS SCANNED SO FAR) ! 24161: # ! 24162: # (WC) DELIMITER ONE (CH$XX) ! 24163: # (XL) DELIMITER TWO (CH$XX) ! 24164: # JSR XSCAN CALL TO SCAN NEXT ITEM ! 24165: # (XR) POINTER TO SCBLK FOR TOKEN SCANNED ! 24166: # (WA) COMPLETION CODE (SEE BELOW) ! 24167: # (WC,XL) DESTROYED ! 24168: # ! 24169: # THE SCAN STARTS FROM THE CURRENT POSITION AND CONTINUES ! 24170: # UNTIL ONE OF THE FOLLOWING THREE CONDITIONS OCCURS. ! 24171: # ! 24172: # 1) DELIMITER ONE IS ENCOUNTERED (WA SET TO 1) ! 24173: # ! 24174: # 2) DELIMITER TWO ENCOUNTERED (WA SET TO 2) ! 24175: # ! 24176: # 3) END OF STRING ENCOUNTERED (WA SET TO 0) ! 24177: # ! 24178: # THE RESULT IS A STRING CONTAINING ALL CHARACTERS SCANNED ! 24179: # UP TO BUT NOT INCLUDING ANY DELIMITER CHARACTER. ! 24180: # THE POINTER IS LEFT POINTING PAST THE DELIMITER. ! 24181: # ! 24182: # IF ONLY ONE DELIMITER IS TO BE DETECTED, DELIMITER ONE ! 24183: # AND DELIMITER TWO SHOULD BE SET TO THE SAME VALUE. ! 24184: # ! 24185: # IN THE CASE WHERE THE END OF STRING IS ENCOUNTERED, THE ! 24186: # STRING INCLUDES ALL THE CHARACTERS TO THE END OF THE ! 24187: # STRING. NO FURTHER CALLS CAN BE MADE TO XSCAN UNTIL ! 24188: # XSCNI IS CALLED TO INITIALIZE A NEW ARGUMENT SCAN ! 24189: #page ! 24190: # ! 24191: # XSCAN (CONTINUED) ! 24192: # ! 24193: xscan: #prc # entry point ! 24194: movl r7,xscwb # preserve wb ! 24195: movl r$xsc,r9 # point to argument string ! 24196: movl 4*sclen(r9),r6 # load string length ! 24197: movl xsofs,r7 # load current offset ! 24198: subl2 r7,r6 # get number of remaining characters ! 24199: tstl r6 # jump if no characters left ! 24200: beqlu xscn2 ! 24201: movab cfp$f(r9)[r7],r9# point to current character ! 24202: # ! 24203: # LOOP TO SEARCH FOR DELIMITER ! 24204: # ! 24205: xscn1: movzbl (r9)+,r7 # load next character ! 24206: cmpl r7,r8 # jump if delimiter one found ! 24207: beqlu xscn3 ! 24208: cmpl r7,r10 # jump if delimiter two found ! 24209: beqlu xscn4 ! 24210: decl r6 # decrement count of chars left ! 24211: tstl r6 # loop back if more chars to go ! 24212: bnequ xscn1 ! 24213: # ! 24214: # HERE FOR RUNOUT ! 24215: # ! 24216: xscn2: movl r$xsc,r10 # point to string block ! 24217: movl 4*sclen(r10),r6 # get string length ! 24218: movl xsofs,r7 # load offset ! 24219: subl2 r7,r6 # get substring length ! 24220: clrl r$xsc # clear string ptr for collector ! 24221: clrl xscrt # set zero (runout) return code ! 24222: jmp xscn6 # jump to exit ! 24223: #page ! 24224: # ! 24225: # XSCAN (CONTINUED) ! 24226: # ! 24227: # HERE IF DELIMITER ONE FOUND ! 24228: # ! 24229: xscn3: movl $num01,xscrt # set return code ! 24230: jmp xscn5 # jump to merge ! 24231: # ! 24232: # HERE IF DELIMITER TWO FOUND ! 24233: # ! 24234: xscn4: movl $num02,xscrt # set return code ! 24235: # ! 24236: # MERGE HERE AFTER DETECTING A DELIMITER ! 24237: # ! 24238: xscn5: movl r$xsc,r10 # reload pointer to string ! 24239: movl 4*sclen(r10),r8 # get original length of string ! 24240: subl2 r6,r8 # minus chars left = chars scanned ! 24241: movl r8,r6 # move to reg for sbstr ! 24242: movl xsofs,r7 # set offset ! 24243: subl2 r7,r6 # compute length for sbstr ! 24244: incl r8 # adjust new cursor past delimiter ! 24245: movl r8,xsofs # store new offset ! 24246: # ! 24247: # COMMON EXIT POINT ! 24248: # ! 24249: xscn6: clrl r9 # clear garbage character ptr in xr ! 24250: jsb sbstr # build sub-string ! 24251: movl xscrt,r6 # load return code ! 24252: movl xscwb,r7 # restore wb ! 24253: rsb # return to xscan caller ! 24254: #enp # end procedure xscan ! 24255: #page ! 24256: # ! 24257: # XSCNI -- EXECUTION FUNCTION ARGUMENT SCAN ! 24258: # ! 24259: # XSCNI INITIALIZES THE SCAN USED FOR PROTOTYPE ARGUMENTS ! 24260: # IN THE CLEAR, DEFINE, LOAD, DATA, ARRAY FUNCTIONS. SEE ! 24261: # XSCAN FOR THE PROCEDURE WHICH IS USED AFTER THIS CALL. ! 24262: # ! 24263: # -(XS) ARGUMENT TO BE SCANNED (ON STACK) ! 24264: # JSR XSCNI CALL TO SCAN ARGUMENT ! 24265: # PPM LOC TRANSFER LOC IF ARG IS NOT STRING ! 24266: # PPM LOC TRANSFER LOC IF ARGUMENT IS NULL ! 24267: # (XS) POPPED ! 24268: # (XR,R$XSC) ARGUMENT (SCBLK PTR) ! 24269: # (WA) ARGUMENT LENGTH ! 24270: # (IA,RA) DESTROYED ! 24271: # ! 24272: .data 1 ! 24273: xscni_s: .long 0 ! 24274: .text 0 ! 24275: xscni: movl (sp)+,xscni_s # entry point ! 24276: jsb gtstg # fetch argument as string ! 24277: .long xsci1 # jump if not convertible ! 24278: movl r9,r$xsc # else store scblk ptr for xscan ! 24279: clrl xsofs # set offset to zero ! 24280: tstl r6 # jump if null string ! 24281: beqlu xsci2 ! 24282: addl3 $4*2,xscni_s,r11 # return to xscni caller ! 24283: jmp (r11) ! 24284: # ! 24285: # HERE IF ARGUMENT IS NOT A STRING ! 24286: # ! 24287: xsci1: movl xscni_s,r11 # take not-string error exit ! 24288: jmp *(r11)+ ! 24289: # ! 24290: # HERE FOR NULL STRING ! 24291: # ! 24292: xsci2: addl3 $4*1,xscni_s,r11 # take null-string error exit ! 24293: jmp *(r11)+ ! 24294: #enp # end procedure xscni ! 24295: #title s p i t b o l -- utility routines ! 24296: # ! 24297: # THE FOLLOWING SECTION CONTAINS UTILITY ROUTINES USED FOR ! 24298: # VARIOUS PURPOSES THROUGHOUT THE SYSTEM. THESE DIFFER ! 24299: # FROM THE PROCEDURES IN THE UTILITY PROCEDURES SECTION IN ! 24300: # THEY ARE NOT IN PROCEDURE FORM AND THEY DO NOT RETURN ! 24301: # TO THEIR CALLERS. THEY ARE ACCESSED WITH A BRANCH TYPE ! 24302: # INSTRUCTION AFTER SETTING THE REGISTERS TO APPROPRIATE ! 24303: # PARAMETER VALUES. ! 24304: # ! 24305: # THE REGISTER VALUES REQUIRED FOR EACH ROUTINE ARE ! 24306: # DOCUMENTED AT THE START OF EACH ROUTINE. REGISTERS NOT ! 24307: # MENTIONED MAY CONTAIN ANY VALUES EXCEPT THAT XR,XL ! 24308: # CAN ONLY CONTAIN PROPER COLLECTABLE POINTERS. ! 24309: # ! 24310: # SOME OF THESE ROUTINES WILL TOLERATE GARBAGE POINTERS ! 24311: # IN XL,XR ON ENTRY. THIS IS ALWAYS DOCUMENTED AND IN ! 24312: # EACH CASE, THE ROUTINE CLEARS THESE GARBAGE VALUES BEFORE ! 24313: # EXITING AFTER COMPLETING ITS TASK. ! 24314: # ! 24315: # THE ROUTINES HAVE NAMES CONSISTING OF FIVE LETTERS ! 24316: # AND ARE ASSEMBLED IN ALPHABETICAL ORDER. ! 24317: #page ! 24318: # ARREF -- ARRAY REFERENCE ! 24319: # ! 24320: # (XL) MAY BE NON-COLLECTABLE ! 24321: # (XR) NUMBER OF SUBSCRIPTS ! 24322: # (WB) SET ZERO/NONZERO FOR VALUE/NAME ! 24323: # THE VALUE IN WB MUST BE COLLECTABLE ! 24324: # STACK SUBSCRIPTS AND ARRAY OPERAND ! 24325: # BRN ARREF JUMP TO CALL FUNCTION ! 24326: # ! 24327: # ARREF CONTINUES BY EXECUTING THE NEXT CODE WORD WITH ! 24328: # THE RESULT NAME OR VALUE PLACED ON TOP OF THE STACK. ! 24329: # TO DEAL WITH THE PROBLEM OF ACCESSING SUBSCRIPTS IN THE ! 24330: # ORDER OF STACKING, XL IS USED AS A SUBSCRIPT POINTER ! 24331: # WORKING BELOW THE STACK POINTER. ! 24332: # ! 24333: arref: #rtn ! 24334: movl r9,r6 # copy number of subscripts ! 24335: movl sp,r10 # point to stack front ! 24336: moval 0[r9],r9 # convert to byte offset ! 24337: addl2 r9,r10 # point to array operand on stack ! 24338: addl2 $4,r10 # final value for stack popping ! 24339: movl r10,arfxs # keep for later ! 24340: movl -(r10),r9 # load array operand pointer ! 24341: movl r9,r$arf # keep array pointer ! 24342: movl r10,r9 # save pointer to subscripts ! 24343: movl r$arf,r10 # point xl to possible vcblk or tbblk ! 24344: movl (r10),r8 # load first word ! 24345: cmpl r8,$b$art # jump if arblk ! 24346: beqlu arf01 ! 24347: cmpl r8,$b$vct # jump if vcblk ! 24348: bnequ 0f ! 24349: jmp arf07 ! 24350: 0: ! 24351: cmpl r8,$b$tbt # jump if tbblk ! 24352: bnequ 0f ! 24353: jmp arf10 ! 24354: 0: ! 24355: jmp er_235 # subscripted operand is not table or array ! 24356: # ! 24357: # HERE FOR ARRAY (ARBLK) ! 24358: # ! 24359: arf01: cmpl r6,4*arndm(r10) # jump if wrong number of dims ! 24360: beqlu 0f ! 24361: jmp arf09 ! 24362: 0: ! 24363: movl intv0,r5 # get initial subscript of zero ! 24364: movl r9,r10 # point before subscripts ! 24365: clrl r6 # initial offset to bounds ! 24366: jmp arf03 # jump into loop ! 24367: # ! 24368: # LOOP TO COMPUTE SUBSCRIPTS BY MULTIPLICATIONS ! 24369: # ! 24370: arf02: mull2 4*ardm2(r9),r5 # multiply total by next dimension ! 24371: # ! 24372: # MERGE HERE FIRST TIME ! 24373: # ! 24374: arf03: movl -(r10),r9 # load next subscript ! 24375: movl r5,arfsi # save current subscript ! 24376: movl 4*icval(r9),r5 # load integer value in case ! 24377: cmpl (r9),$b$icl # jump if it was an integer ! 24378: beqlu arf04 ! 24379: #page ! 24380: # ! 24381: # ARREF (CONTINUED) ! 24382: # ! 24383: # ! 24384: jsb gtint # convert to integer ! 24385: .long arf12 # jump if not integer ! 24386: movl 4*icval(r9),r5 # if ok, load integer value ! 24387: # ! 24388: # HERE WITH INTEGER SUBSCRIPT IN (IA) ! 24389: # ! 24390: arf04: movl r$arf,r9 # point to array ! 24391: addl2 r6,r9 # offset to next bounds ! 24392: subl2 4*arlbd(r9),r5 # subtract low bound to compare ! 24393: bvc 0f ! 24394: jmp arf13 ! 24395: 0: ! 24396: tstl r5 # out of range fail if too small ! 24397: bgeq 0f ! 24398: jmp arf13 ! 24399: 0: ! 24400: subl2 4*ardim(r9),r5 # subtract dimension ! 24401: tstl r5 # out of range fail if too large ! 24402: blss 0f ! 24403: jmp arf13 ! 24404: 0: ! 24405: addl2 4*ardim(r9),r5 # else restore subscript offset ! 24406: addl2 arfsi,r5 # add to current total ! 24407: addl2 $4*ardms,r6 # point to next bounds ! 24408: cmpl r10,sp # loop back if more to go ! 24409: bnequ arf02 ! 24410: # ! 24411: # HERE WITH INTEGER SUBSCRIPT COMPUTED ! 24412: # ! 24413: movl r5,r6 # get as one word integer ! 24414: moval 0[r6],r6 # convert to offset ! 24415: movl r$arf,r10 # point to arblk ! 24416: addl2 4*arofs(r10),r6 # add offset past bounds ! 24417: addl2 $4,r6 # adjust for arpro field ! 24418: tstl r7 # exit with name if name call ! 24419: bnequ arf08 ! 24420: # ! 24421: # MERGE HERE TO GET VALUE FOR VALUE CALL ! 24422: # ! 24423: arf05: jsb acess # get value ! 24424: .long arf13 # fail if acess fails ! 24425: # ! 24426: # RETURN VALUE ! 24427: # ! 24428: arf06: movl arfxs,sp # pop stack entries ! 24429: clrl r$arf # finished with array pointer ! 24430: jmp exixr # exit with value in xr ! 24431: #page ! 24432: # ! 24433: # ARREF (CONTINUED) ! 24434: # ! 24435: # HERE FOR VECTOR ! 24436: # ! 24437: arf07: cmpl r6,$num01 # error if more than 1 subscript ! 24438: beqlu 0f ! 24439: jmp arf09 ! 24440: 0: ! 24441: movl (sp),r9 # else load subscript ! 24442: jsb gtint # convert to integer ! 24443: .long arf12 # error if not integer ! 24444: movl 4*icval(r9),r5 # else load integer value ! 24445: subl2 intv1,r5 # subtract for ones offset ! 24446: movl r5,r6 # get subscript as one word ! 24447: bgeq 0f ! 24448: jmp arf13 ! 24449: 0: ! 24450: addl2 $vcvls,r6 # add offset for standard fields ! 24451: moval 0[r6],r6 # convert offset to bytes ! 24452: cmpl r6,4*vclen(r10) # fail if out of range subscript ! 24453: blssu 0f ! 24454: jmp arf13 ! 24455: 0: ! 24456: tstl r7 # back to get value if value call ! 24457: beqlu arf05 ! 24458: # ! 24459: # RETURN NAME ! 24460: # ! 24461: arf08: movl arfxs,sp # pop stack entries ! 24462: clrl r$arf # finished with array pointer ! 24463: jmp exnam # else exit with name ! 24464: # ! 24465: # HERE IF SUBSCRIPT COUNT IS WRONG ! 24466: # ! 24467: arf09: jmp er_236 # array referenced with wrong number of subscripts ! 24468: # ! 24469: # TABLE ! 24470: # ! 24471: arf10: cmpl r6,$num01 # error if more than 1 subscript ! 24472: bnequ arf11 ! 24473: movl (sp),r9 # else load subscript ! 24474: jsb tfind # call table search routine ! 24475: .long arf13 # fail if failed ! 24476: tstl r7 # exit with name if name call ! 24477: bnequ arf08 ! 24478: jmp arf06 # else exit with value ! 24479: # ! 24480: # HERE FOR BAD TABLE REFERENCE ! 24481: # ! 24482: arf11: jmp er_237 # table referenced with more than one subscript ! 24483: # ! 24484: # HERE FOR BAD SUBSCRIPT ! 24485: # ! 24486: arf12: jmp er_238 # array subscript is not integer ! 24487: # ! 24488: # HERE TO SIGNAL FAILURE ! 24489: # ! 24490: arf13: clrl r$arf # finished with array pointer ! 24491: jmp exfal # fail ! 24492: #page ! 24493: # ! 24494: # CFUNC -- CALL A FUNCTION ! 24495: # ! 24496: # CFUNC IS USED TO CALL A SNOBOL LEVEL FUNCTION. IT IS ! 24497: # USED BY THE APPLY FUNCTION (S$APP), THE FUNCTION ! 24498: # TRACE ROUTINE (TRXEQ) AND THE MAIN FUNCTION CALL ENTRY ! 24499: # (O$FNC, O$FNS). IN THE LATTER CASES, CFUNC IS USED ONLY ! 24500: # IF THE NUMBER OF ARGUMENTS IS INCORRECT. ! 24501: # ! 24502: # (XL) POINTER TO FUNCTION BLOCK ! 24503: # (WA) ACTUAL NUMBER OF ARGUMENTS ! 24504: # (XS) POINTS TO STACKED ARGUMENTS ! 24505: # BRN CFUNC JUMP TO CALL FUNCTION ! 24506: # ! 24507: # CFUNC CONTINUES BY EXECUTING THE FUNCTION ! 24508: # ! 24509: cfunc: #rtn ! 24510: cmpl r6,4*fargs(r10) # jump if too few arguments ! 24511: blssu cfnc1 ! 24512: cmpl r6,4*fargs(r10) # jump if correct number of args ! 24513: beqlu cfnc3 ! 24514: # ! 24515: # HERE IF TOO MANY ARGUMENTS SUPPLIED, POP THEM OFF ! 24516: # ! 24517: movl r6,r7 # copy actual number ! 24518: subl2 4*fargs(r10),r7 # get number of extra args ! 24519: moval 0[r7],r7 # convert to bytes ! 24520: addl2 r7,sp # pop off unwanted arguments ! 24521: jmp cfnc3 # jump to go off to function ! 24522: # ! 24523: # HERE IF TOO FEW ARGUMENTS ! 24524: # ! 24525: cfnc1: movl 4*fargs(r10),r7 # load required number of arguments ! 24526: cmpl r7,$nini9 # jump if case of var num of args ! 24527: beqlu cfnc3 ! 24528: subl2 r6,r7 # calculate number missing ! 24529: # set counter to control loop ! 24530: # ! 24531: # LOOP TO SUPPLY EXTRA NULL ARGUMENTS ! 24532: # ! 24533: cfnc2: movl $nulls,-(sp) # stack a null argument ! 24534: sobgtr r7,cfnc2 # loop till proper number stacked ! 24535: # ! 24536: # MERGE HERE TO JUMP TO FUNCTION ! 24537: # ! 24538: cfnc3: movl (r10),r11 # jump through fcode field ! 24539: jmp (r11) ! 24540: #page ! 24541: # ! 24542: # EXFAL -- EXIT SIGNALLING SNOBOL FAILURE ! 24543: # ! 24544: # (XL,XR) MAY BE NON-COLLECTABLE ! 24545: # BRN EXFAL JUMP TO FAIL ! 24546: # ! 24547: # EXFAL CONTINUES BY EXECUTING THE APPROPRIATE FAIL GOTO ! 24548: # ! 24549: exfal: #rtn ! 24550: movl flptr,sp # pop stack ! 24551: movl (sp),r9 # load failure offset ! 24552: addl2 r$cod,r9 # point to failure code location ! 24553: movl r9,r3 # set code pointer ! 24554: jmp exits # do next code word ! 24555: #page ! 24556: # ! 24557: # EXINT -- EXIT WITH INTEGER RESULT ! 24558: # ! 24559: # (XL,XR) MAY BE NONCOLLECTABLE ! 24560: # (IA) INTEGER VALUE ! 24561: # BRN EXINT JUMP TO EXIT WITH INTEGER ! 24562: # ! 24563: # EXINT CONTINUES BY EXECUTING THE NEXT CODE WORD ! 24564: # WHICH IT DOES BY FALLING THROUGH TO EXIXR ! 24565: # ! 24566: exint: #rtn ! 24567: jsb icbld # build icblk ! 24568: #page ! 24569: # EXIXR -- EXIT WITH RESULT IN (XR) ! 24570: # ! 24571: # (XR) RESULT ! 24572: # (XL) MAY BE NON-COLLECTABLE ! 24573: # BRN EXIXR JUMP TO EXIT WITH RESULT IN (XR) ! 24574: # ! 24575: # EXIXR CONTINUES BY EXECUTING THE NEXT CODE WORD ! 24576: # WHICH IT DOES BY FALLING THROUGH TO EXITS. ! 24577: exixr: #rtn ! 24578: # ! 24579: movl r9,-(sp) # stack result ! 24580: # ! 24581: # ! 24582: # EXITS -- EXIT WITH RESULT IF ANY STACKED ! 24583: # ! 24584: # (XR,XL) MAY BE NON-COLLECTABLE ! 24585: # ! 24586: # BRN EXITS ENTER EXITS ROUTINE ! 24587: # ! 24588: exits: #rtn ! 24589: movl (r3)+,r9 # load next code word ! 24590: movl (r9),r10 # load entry address ! 24591: movl r10,r11 # jump to execute next code word ! 24592: jmp (r11) ! 24593: #page ! 24594: # ! 24595: # EXNAM -- EXIT WITH NAME IN (XL,WA) ! 24596: # ! 24597: # (XL) NAME BASE ! 24598: # (WA) NAME OFFSET ! 24599: # (XR) MAY BE NON-COLLECTABLE ! 24600: # BRN EXNAM JUMP TO EXIT WITH NAME IN (XL,WA) ! 24601: # ! 24602: # EXNAM CONTINUES BY EXECUTING THE NEXT CODE WORD ! 24603: # ! 24604: exnam: #rtn ! 24605: movl r10,-(sp) # stack name base ! 24606: movl r6,-(sp) # stack name offset ! 24607: jmp exits # do next code word ! 24608: #page ! 24609: # ! 24610: # EXNUL -- EXIT WITH NULL RESULT ! 24611: # ! 24612: # (XL,XR) MAY BE NON-COLLECTABLE ! 24613: # BRN EXNUL JUMP TO EXIT WITH NULL VALUE ! 24614: # ! 24615: # EXNUL CONTINUES BY EXECUTING THE NEXT CODE WORD ! 24616: # ! 24617: exnul: #rtn ! 24618: movl $nulls,-(sp) # stack null value ! 24619: jmp exits # do next code word ! 24620: #page ! 24621: # ! 24622: # EXREA -- EXIT WITH REAL RESULT ! 24623: # ! 24624: # (XL,XR) MAY BE NON-COLLECTABLE ! 24625: # (RA) REAL VALUE ! 24626: # BRN EXREA JUMP TO EXIT WITH REAL VALUE ! 24627: # ! 24628: # EXREA CONTINUES BY EXECUTING THE NEXT CODE WORD ! 24629: # ! 24630: exrea: #rtn ! 24631: jsb rcbld # build rcblk ! 24632: jmp exixr # jump to exit with result in xr ! 24633: #page ! 24634: # ! 24635: # EXSID -- EXIT SETTING ID FIELD ! 24636: # ! 24637: # EXSID IS USED TO EXIT AFTER BUILDING ANY OF THE FOLLOWING ! 24638: # BLOCKS (ARBLK, TBBLK, PDBLK, VCBLK). IT SETS THE IDVAL. ! 24639: # ! 24640: # (XR) PTR TO BLOCK WITH IDVAL FIELD ! 24641: # (XL) MAY BE NON-COLLECTABLE ! 24642: # BRN EXSID JUMP TO EXIT AFTER SETTING ID FIELD ! 24643: # ! 24644: # EXSID CONTINUES BY EXECUTING THE NEXT CODE WORD ! 24645: # ! 24646: exsid: #rtn ! 24647: movl curid,r6 # load current id value ! 24648: cmpl r6,$cfp$m # jump if no overflow ! 24649: bnequ exsi1 ! 24650: clrl r6 # else reset for wraparound ! 24651: # ! 24652: # HERE WITH OLD IDVAL IN WA ! 24653: # ! 24654: exsi1: incl r6 # bump id value ! 24655: movl r6,curid # store for next time ! 24656: movl r6,4*idval(r9) # store id value ! 24657: jmp exixr # exit with result in (xr) ! 24658: #page ! 24659: # ! 24660: # EXVNM -- EXIT WITH NAME OF VARIABLE ! 24661: # ! 24662: # EXVNM EXITS AFTER STACKING A VALUE WHICH IS A NMBLK ! 24663: # REFERENCING THE NAME OF A GIVEN NATURAL VARIABLE. ! 24664: # ! 24665: # (XR) VRBLK POINTER ! 24666: # (XL) MAY BE NON-COLLECTABLE ! 24667: # BRN EXVNM EXIT WITH VRBLK POINTER IN XR ! 24668: # ! 24669: exvnm: #rtn ! 24670: movl r9,r10 # copy name base pointer ! 24671: movl $4*nmsi$,r6 # set size of nmblk ! 24672: jsb alloc # allocate nmblk ! 24673: movl $b$nml,(r9) # store type word ! 24674: movl r10,4*nmbas(r9) # store name base ! 24675: movl $4*vrval,4*nmofs(r9) # store name offset ! 24676: jmp exixr # exit with result in xr ! 24677: #page ! 24678: # ! 24679: # FLPOP -- FAIL AND POP IN PATTERN MATCHING ! 24680: # ! 24681: # FLPOP POPS THE NODE AND CURSOR ON THE STACK AND THEN ! 24682: # DROPS THROUGH INTO FAILP TO CAUSE PATTERN FAILURE ! 24683: # ! 24684: # (XL,XR) MAY BE NON-COLLECTABLE ! 24685: # BRN FLPOP JUMP TO FAIL AND POP STACK ! 24686: # ! 24687: flpop: #rtn ! 24688: addl2 $4*num02,sp # pop two entries off stack ! 24689: #page ! 24690: # ! 24691: # FAILP -- FAILURE IN MATCHING PATTERN NODE ! 24692: # ! 24693: # FAILP IS USED AFTER FAILING TO MATCH A PATTERN NODE. ! 24694: # SEE PATTERN MATCH ROUTINES FOR DETAILS OF USE. ! 24695: # ! 24696: # (XL,XR) MAY BE NON-COLLECTABLE ! 24697: # BRN FAILP SIGNAL FAILURE TO MATCH ! 24698: # ! 24699: # FAILP CONTINUES BY MATCHING AN ALTERNATIVE FROM THE STACK ! 24700: # ! 24701: failp: #rtn ! 24702: movl (sp)+,r9 # load alternative node pointer ! 24703: movl (sp)+,r7 # restore old cursor ! 24704: movl (r9),r10 # load pcode entry pointer ! 24705: movl r10,r11 # jump to execute code for node ! 24706: jmp (r11) ! 24707: #page ! 24708: # ! 24709: # INDIR -- COMPUTE INDIRECT REFERENCE ! 24710: # ! 24711: # (WB) NONZERO/ZERO FOR BY NAME/VALUE ! 24712: # BRN INDIR JUMP TO GET INDIRECT REF ON STACK ! 24713: # ! 24714: # INDIR CONTINUES BY EXECUTING THE NEXT CODE WORD ! 24715: # ! 24716: indir: #rtn ! 24717: movl (sp)+,r9 # load argument ! 24718: cmpl (r9),$b$nml # jump if a name ! 24719: beqlu indr2 ! 24720: jsb gtnvr # else convert to variable ! 24721: .long er_239 # indirection operand is not name ! 24722: tstl r7 # skip if by value ! 24723: beqlu indr1 ! 24724: movl r9,-(sp) # else stack vrblk ptr ! 24725: movl $4*vrval,-(sp) # stack name offset ! 24726: jmp exits # exit with result on stack ! 24727: # ! 24728: # HERE TO GET VALUE OF NATURAL VARIABLE ! 24729: # ! 24730: indr1: movl (r9),r11 # jump through vrget field of vrblk ! 24731: jmp (r11) ! 24732: # ! 24733: # HERE IF OPERAND IS A NAME ! 24734: # ! 24735: indr2: movl 4*nmbas(r9),r10 # load name base ! 24736: movl 4*nmofs(r9),r6 # load name offset ! 24737: tstl r7 # exit if called by name ! 24738: beqlu 0f ! 24739: jmp exnam ! 24740: 0: ! 24741: jsb acess # else get value first ! 24742: .long exfal # fail if access fails ! 24743: jmp exixr # else return with value in xr ! 24744: #page ! 24745: # ! 24746: # MATCH -- INITIATE PATTERN MATCH ! 24747: # ! 24748: # (WB) MATCH TYPE CODE ! 24749: # BRN MATCH JUMP TO INITIATE PATTERN MATCH ! 24750: # ! 24751: # MATCH CONTINUES BY EXECUTING THE PATTERN MATCH. SEE ! 24752: # PATTERN MATCH ROUTINES (P$XXX) FOR FULL DETAILS. ! 24753: # ! 24754: match: #rtn ! 24755: movl (sp)+,r9 # load pattern operand ! 24756: jsb gtpat # convert to pattern ! 24757: .long er_240 # pattern match right operand is not pattern ! 24758: movl r9,r10 # if ok, save pattern pointer ! 24759: tstl r7 # jump if not match by name ! 24760: bnequ mtch1 ! 24761: movl (sp),r6 # else load name offset ! 24762: movl r10,-(sp) # save pattern pointer ! 24763: movl 4*2(sp),r10 # load name base ! 24764: jsb acess # access subject value ! 24765: .long exfal # fail if access fails ! 24766: movl (sp),r10 # restore pattern pointer ! 24767: movl r9,(sp) # stack subject string val for merge ! 24768: clrl r7 # restore type code ! 24769: # ! 24770: # MERGE HERE WITH SUBJECT VALUE ON STACK ! 24771: # ! 24772: mtch1: movl (sp),r9 # load subject value ! 24773: clrl r$pmb # assume not a buffer ! 24774: cmpl (r9),$b$bct # branch if not ! 24775: bnequ mtcha ! 24776: addl2 $4,sp # else pop value ! 24777: movl r9,r$pmb # save pointer ! 24778: movl 4*bclen(r9),r6 # get defined length ! 24779: movl 4*bcbuf(r9),r9 # point to bfblk ! 24780: jmp mtchb ! 24781: # ! 24782: # HERE IF NOT BUFFER TO CONVERT TO STRING ! 24783: # ! 24784: mtcha: jsb gtstg # not buffer - convert to string ! 24785: .long er_241 # pattern match left operand is not string ! 24786: # ! 24787: # MERGE WITH BUFFER OR STRING ! 24788: # ! 24789: mtchb: movl r9,r$pms # if ok, store subject string pointer ! 24790: movl r6,pmssl # and length ! 24791: movl r7,-(sp) # stack match type code ! 24792: clrl -(sp) # stack initial cursor (zero) ! 24793: clrl r7 # set initial cursor ! 24794: movl sp,pmhbs # set history stack base ptr ! 24795: clrl pmdfl # reset pattern assignment flag ! 24796: movl r10,r9 # set initial node pointer ! 24797: tstl kvanc # jump if anchored ! 24798: bnequ mtch2 ! 24799: # ! 24800: # HERE FOR UNANCHORED ! 24801: # ! 24802: movl r9,-(sp) # stack initial node pointer ! 24803: movl $nduna,-(sp) # stack pointer to anchor move node ! 24804: movl (r9),r11 # start match of first node ! 24805: jmp (r11) ! 24806: # ! 24807: # HERE IN ANCHORED MODE ! 24808: # ! 24809: mtch2: clrl -(sp) # dummy cursor value ! 24810: movl $ndabo,-(sp) # stack pointer to abort node ! 24811: movl (r9),r11 # start match of first node ! 24812: jmp (r11) ! 24813: #page ! 24814: # ! 24815: # RETRN -- RETURN FROM FUNCTION ! 24816: # ! 24817: # (WA) STRING POINTER FOR RETURN TYPE ! 24818: # BRN RETRN JUMP TO RETURN FROM (SNOBOL) FUNC ! 24819: # ! 24820: # RETRN CONTINUES BY EXECUTING THE CODE AT THE RETURN POINT ! 24821: # THE STACK IS CLEANED OF ANY GARBAGE LEFT BY OTHER ! 24822: # ROUTINES WHICH MAY HAVE ALTERED FLPTR SINCE FUNCTION ! 24823: # ENTRY BY USING FLPRT, RESERVED FOR USE ONLY BY ! 24824: # FUNCTION CALL AND RETURN. ! 24825: # ! 24826: retrn: #rtn ! 24827: tstl kvfnc # jump if not level zero ! 24828: bnequ rtn01 ! 24829: jmp er_242 # function return from level zero ! 24830: # ! 24831: # HERE IF NOT LEVEL ZERO RETURN ! 24832: # ! 24833: rtn01: movl flprt,sp # pop stack ! 24834: addl2 $4,sp # remove failure offset ! 24835: movl (sp)+,r9 # pop pfblk pointer ! 24836: movl (sp)+,flptr # pop failure pointer ! 24837: movl (sp)+,flprt # pop old flprt ! 24838: movl (sp)+,r7 # pop code pointer offset ! 24839: movl (sp)+,r8 # pop old code block pointer ! 24840: addl2 r8,r7 # make old code pointer absolute ! 24841: movl r7,r3 # restore old code pointer ! 24842: movl r8,r$cod # restore old code block pointer ! 24843: decl kvfnc # decrement function level ! 24844: movl kvtra,r7 # load trace ! 24845: addl2 kvftr,r7 # add ftrace ! 24846: tstl r7 # jump if no tracing possible ! 24847: bnequ 0f ! 24848: jmp rtn06 ! 24849: 0: ! 24850: # ! 24851: # HERE IF THERE MAY BE A TRACE ! 24852: # ! 24853: movl r6,-(sp) # save function return type ! 24854: movl r9,-(sp) # save pfblk pointer ! 24855: movl r6,kvrtn # set rtntype for trace function ! 24856: movl r$fnc,r10 # load fnclevel trblk ptr (if any) ! 24857: jsb ktrex # execute possible fnclevel trace ! 24858: movl 4*pfvbl(r9),r10 # load vrblk ptr (sgd13) ! 24859: tstl kvtra # jump if trace is off ! 24860: beqlu rtn02 ! 24861: movl 4*pfrtr(r9),r9 # else load return trace trblk ptr ! 24862: tstl r9 # jump if not return traced ! 24863: beqlu rtn02 ! 24864: decl kvtra # else decrement trace count ! 24865: tstl 4*trfnc(r9) # jump if print trace ! 24866: beqlu rtn03 ! 24867: movl $4*vrval,r6 # else set name offset ! 24868: movl 4*1(sp),kvrtn # make sure rtntype is set right ! 24869: jsb trxeq # execute full trace ! 24870: #page ! 24871: # ! 24872: # RETRN (CONTINUED) ! 24873: # ! 24874: # HERE TO TEST FOR FTRACE ! 24875: # ! 24876: rtn02: tstl kvftr # jump if ftrace is off ! 24877: beqlu rtn05 ! 24878: decl kvftr # else decrement ftrace ! 24879: # ! 24880: # HERE FOR PRINT TRACE OF FUNCTION RETURN ! 24881: # ! 24882: rtn03: jsb prtsn # print statement number ! 24883: movl 4*1(sp),r9 # load return type ! 24884: jsb prtst # print it ! 24885: movl $ch$bl,r6 # load blank ! 24886: jsb prtch # print it ! 24887: movl (sp),r10 # load pfblk ptr ! 24888: movl 4*pfvbl(r10),r10# load function vrblk ptr ! 24889: movl $4*vrval,r6 # set vrblk name offset ! 24890: cmpl r9,$scfrt # jump if not freturn case ! 24891: bnequ rtn04 ! 24892: # ! 24893: # FOR FRETURN, JUST PRINT FUNCTION NAME ! 24894: # ! 24895: jsb prtnm # print name ! 24896: jsb prtnl # terminate print line ! 24897: jmp rtn05 # merge ! 24898: # ! 24899: # HERE FOR RETURN OR NRETURN, PRINT FUNCTION NAME = VALUE ! 24900: # ! 24901: rtn04: jsb prtnv # print name = value ! 24902: # ! 24903: # HERE AFTER COMPLETING TRACE ! 24904: # ! 24905: rtn05: movl (sp)+,r9 # pop pfblk pointer ! 24906: movl (sp)+,r6 # pop return type string ! 24907: # ! 24908: # MERGE HERE IF NO TRACE REQUIRED ! 24909: # ! 24910: rtn06: movl r6,kvrtn # set rtntype keyword ! 24911: movl 4*pfvbl(r9),r10 # load pointer to fn vrblk ! 24912: #page ! 24913: # RETRN (CONTINUED) ! 24914: # ! 24915: # GET VALUE OF FUNCTION ! 24916: # ! 24917: rtn07: movl r10,rtnbp # save block pointer ! 24918: movl 4*vrval(r10),r10# load value ! 24919: cmpl (r10),$b$trt # loop back if trapped ! 24920: beqlu rtn07 ! 24921: movl r10,rtnfv # else save function result value ! 24922: movl (sp)+,rtnsv # save original function value ! 24923: movl (sp)+,r10 # pop saved pointer ! 24924: tstl r10 # no action if none ! 24925: beqlu rtn7c ! 24926: tstl kvpfl # jump if no profiling ! 24927: beqlu rtn7c ! 24928: jsb prflu # else profile last func stmt ! 24929: cmpl kvpfl,$num02 # branch on value of profile keywd ! 24930: beqlu rtn7a ! 24931: # ! 24932: # HERE IF &PROFILE = 1. START TIME MUST BE FRIGGED TO ! 24933: # APPEAR EARLIER THAN IT ACTUALLY IS, BY AMOUNT USED BEFORE ! 24934: # THE CALL. ! 24935: # ! 24936: movl pfstm,r5 # load current time ! 24937: subl2 4*icval(r10),r5 # frig by subtracting saved amount ! 24938: jmp rtn7b # and merge ! 24939: # ! 24940: # HERE IF &PROFILE = 2 ! 24941: # ! 24942: rtn7a: movl 4*icval(r10),r5 # load saved time ! 24943: # ! 24944: # BOTH PROFILE TYPES MERGE HERE ! 24945: # ! 24946: rtn7b: movl r5,pfstm # store back correct start time ! 24947: # ! 24948: # MERGE HERE IF NO PROFILING ! 24949: # ! 24950: rtn7c: movl 4*fargs(r9),r7 # get number of args ! 24951: addl2 4*pfnlo(r9),r7 # add number of locals ! 24952: tstl r7 # jump if no args/locals ! 24953: beqlu rtn10 ! 24954: # else set loop counter ! 24955: addl2 4*pflen(r9),r9 # and point to end of pfblk ! 24956: # ! 24957: # LOOP TO RESTORE FUNCTIONS AND LOCALS ! 24958: # ! 24959: rtn08: movl -(r9),r10 # load next vrblk pointer ! 24960: # ! 24961: # LOOP TO FIND VALUE BLOCK ! 24962: # ! 24963: rtn09: movl r10,r6 # save block pointer ! 24964: movl 4*vrval(r10),r10# load pointer to next value ! 24965: cmpl (r10),$b$trt # loop back if trapped ! 24966: beqlu rtn09 ! 24967: movl r6,r10 # else restore last block pointer ! 24968: movl (sp)+,4*vrval(r10) # restore old variable value ! 24969: sobgtr r7,rtn08 # loop till all processed ! 24970: # ! 24971: # NOW RESTORE FUNCTION VALUE AND EXIT ! 24972: # ! 24973: rtn10: movl rtnbp,r10 # restore ptr to last function block ! 24974: movl rtnsv,4*vrval(r10) # restore old function value ! 24975: movl rtnfv,r9 # reload function result ! 24976: movl r$cod,r10 # point to new code block ! 24977: movl kvstn,kvlst # set lastno from stno ! 24978: movl 4*cdstm(r10),kvstn # reset proper stno value ! 24979: movl kvrtn,r6 # load return type ! 24980: cmpl r6,$scrtn # exit with result in xr if return ! 24981: bnequ 0f ! 24982: jmp exixr ! 24983: 0: ! 24984: cmpl r6,$scfrt # fail if freturn ! 24985: bnequ 0f ! 24986: jmp exfal ! 24987: 0: ! 24988: #page ! 24989: # ! 24990: # RETRN (CONTINUED) ! 24991: # ! 24992: # HERE FOR NRETURN ! 24993: # ! 24994: cmpl (r9),$b$nml # jump if is a name ! 24995: beqlu rtn11 ! 24996: jsb gtnvr # else try convert to variable name ! 24997: .long er_243 # function result in nreturn is not name ! 24998: movl r9,r10 # if ok, copy vrblk (name base) ptr ! 24999: movl $4*vrval,r6 # set name offset ! 25000: jmp rtn12 # and merge ! 25001: # ! 25002: # HERE IF RETURNED RESULT IS A NAME ! 25003: # ! 25004: rtn11: movl 4*nmbas(r9),r10 # load name base ! 25005: movl 4*nmofs(r9),r6 # load name offset ! 25006: # ! 25007: # MERGE HERE WITH RETURNED NAME IN (XL,WA) ! 25008: # ! 25009: rtn12: movl r10,r9 # preserve xl ! 25010: movl (r3)+,r7 # load next word ! 25011: movl r9,r10 # restore xl ! 25012: cmpl r7,$ofne$ # exit if called by name ! 25013: bnequ 0f ! 25014: jmp exnam ! 25015: 0: ! 25016: movl r7,-(sp) # else save code word ! 25017: jsb acess # get value ! 25018: .long exfal # fail if access fails ! 25019: movl r9,r10 # if ok, copy result ! 25020: movl (sp),r9 # reload next code word ! 25021: movl r10,(sp) # store result on stack ! 25022: movl (r9),r10 # load routine address ! 25023: movl r10,r11 # jump to execute next code word ! 25024: jmp (r11) ! 25025: #page ! 25026: # ! 25027: # STCOV -- SIGNAL STATEMENT COUNTER OVERFLOW ! 25028: # ! 25029: # BRN STCOV JUMP TO SIGNAL STATEMENT COUNT OFLO ! 25030: # ! 25031: # PERMIT UP TO 10 MORE STATEMENTS TO BE OBEYED SO THAT ! 25032: # SETEXIT TRAP CAN REGAIN CONTROL. ! 25033: # STCOV CONTINUES BY ISSUING THE ERROR MESSAGE ! 25034: # ! 25035: stcov: #rtn ! 25036: incl errft # fatal error ! 25037: movl intvt,r5 # get 10 ! 25038: addl2 kvstl,r5 # add to former limit ! 25039: movl r5,kvstl # store as new stlimit ! 25040: movl intvt,r5 # get 10 ! 25041: movl r5,kvstc # set as new count ! 25042: jmp er_244 # statement count exceeds value of stlimit keyword ! 25043: #page ! 25044: # ! 25045: # STMGO -- START EXECUTION OF NEW STATEMENT ! 25046: # ! 25047: # (XR) POINTER TO CDBLK FOR NEW STATEMENT ! 25048: # BRN STMGO JUMP TO EXECUTE NEW STATEMENT ! 25049: # ! 25050: # STMGO CONTINUES BY EXECUTING THE NEXT STATEMENT ! 25051: # ! 25052: stmgo: #rtn ! 25053: movl r9,r$cod # set new code block pointer ! 25054: tstl kvpfl # skip if no profiling ! 25055: beqlu stgo1 ! 25056: jsb prflu # else profile the statement ! 25057: stgo1: movl kvstn,kvlst # set lastno ! 25058: movl 4*cdstm(r9),kvstn# set stno ! 25059: addl2 $4*cdcod,r9 # point to first code word ! 25060: movl r9,r3 # set code pointer ! 25061: movl kvstc,r5 # get stmt count ! 25062: tstl r5 # omit counting if negative ! 25063: bgeq 0f ! 25064: jmp exits ! 25065: 0: ! 25066: tstl r5 # fail if stlimit reached ! 25067: beql stcov ! 25068: subl2 intv1,r5 # decrement ! 25069: movl r5,kvstc # replace it ! 25070: tstl r$stc # exit if no stcount trace ! 25071: bnequ 0f ! 25072: jmp exits ! 25073: 0: ! 25074: # ! 25075: # HERE FOR STCOUNT TRACE ! 25076: # ! 25077: clrl r9 # clear garbage value in xr ! 25078: movl r$stc,r10 # load pointer to stcount trblk ! 25079: jsb ktrex # execute keyword trace ! 25080: jmp exits # and then exit for next code word ! 25081: #page ! 25082: # ! 25083: # STOPR -- TERMINATE RUN ! 25084: # ! 25085: # (XR) POINTS TO ENDING MESSAGE ! 25086: # BRN STOPR JUMP TO TERMINATE RUN ! 25087: # ! 25088: # TERMINATE RUN AND PRINT STATISTICS. ON ENTRY XR POINTS ! 25089: # TO ENDING MESSAGE OR IS ZERO IF MESSAGE PRINTED ALREADY. ! 25090: # ! 25091: stopr: #rtn ! 25092: tstl r9 # skip if sysax already called (reg04) ! 25093: beqlu stpra ! 25094: jsb sysax # call after execution proc ! 25095: stpra: addl2 rsmem,dname # use the reserve memory ! 25096: cmpl r9,$endms # skip if not normal end message ! 25097: bnequ stpr0 ! 25098: tstl exsts # skip if exec stats suppressed ! 25099: beqlu 0f ! 25100: jmp stpr3 ! 25101: 0: ! 25102: clrl erich # clear errors to int.ch. flag ! 25103: # ! 25104: # LOOK TO SEE IF AN ENDING MESSAGE IS SUPPLIED ! 25105: # ! 25106: stpr0: jsb prtpg # eject printer ! 25107: tstl r9 # skip if no message ! 25108: beqlu stpr1 ! 25109: jsb prtst # print message ! 25110: # ! 25111: # MERGE HERE IF NO MESSAGE TO PRINT ! 25112: # ! 25113: stpr1: jsb prtis # print blank line ! 25114: movl kvstn,r5 # get statement number ! 25115: movl $stpm1,r9 # point to message /in statement xxx/ ! 25116: jsb prtmx # print it ! 25117: jsb systm # get current time ! 25118: subl2 timsx,r5 # minus start time = elapsed exec tim ! 25119: movl r5,stpti # save for later ! 25120: movl $stpm3,r9 # point to msg /execution time msec / ! 25121: jsb prtmx # print it ! 25122: movl kvstl,r5 # get statement limit ! 25123: tstl r5 # skip if negative ! 25124: blss stpr2 ! 25125: subl2 kvstc,r5 # minus counter = count ! 25126: movl r5,stpsi # save ! 25127: movl $stpm2,r9 # point to message /stmts executed/ ! 25128: jsb prtmx # print it ! 25129: movl stpti,r5 # reload elapsed time ! 25130: mull2 intth,r5 # *1000 (microsecs) ! 25131: bvs stpr2 ! 25132: divl2 stpsi,r5 # divide by statement count ! 25133: bvs stpr2 ! 25134: movl $stpm4,r9 # point to msg (mcsec per statement / ! 25135: jsb prtmx # print it ! 25136: #page ! 25137: # ! 25138: # STOPR (CONTINUED) ! 25139: # ! 25140: # MERGE TO SKIP MESSAGE (OVERFLOW OR NEGATIVE STLIMIT) ! 25141: # ! 25142: stpr2: movl gbcnt,r5 # load count of collections ! 25143: movl $stpm5,r9 # point to message /regenerations / ! 25144: jsb prtmx # print it ! 25145: jsb prtis # one more blank for luck ! 25146: # ! 25147: # CHECK IF DUMP REQUESTED ! 25148: # ! 25149: stpr3: jsb prflr # print profile if wanted ! 25150: # ! 25151: movl kvdmp,r9 # load dump keyword ! 25152: jsb dumpr # execute dump if requested ! 25153: movl r$fcb,r10 # get fcblk chain head ! 25154: movl kvabe,r6 # load abend value ! 25155: movl kvcod,r7 # load code value ! 25156: jsb sysej # exit to system ! 25157: #page ! 25158: # ! 25159: # SUCCP -- SIGNAL SUCCESSFUL MATCH OF A PATTERN NODE ! 25160: # ! 25161: # SEE PATTERN MATCH ROUTINES FOR DETAILS ! 25162: # ! 25163: # (XR) CURRENT NODE ! 25164: # (WB) CURRENT CURSOR ! 25165: # (XL) MAY BE NON-COLLECTABLE ! 25166: # BRN SUCCP SIGNAL SUCCESSFUL PATTERN MATCH ! 25167: # ! 25168: # SUCCP CONTINUES BY MATCHING THE SUCCESSOR NODE ! 25169: # ! 25170: succp: #rtn ! 25171: movl 4*pthen(r9),r9 # load successor node ! 25172: movl (r9),r10 # load node code entry address ! 25173: movl r10,r11 # jump to match successor node ! 25174: jmp (r11) ! 25175: #page ! 25176: # ! 25177: # SYSAB -- PRINT /ABNORMAL END/ AND TERMINATE ! 25178: # ! 25179: sysab: #rtn ! 25180: movl $endab,r9 # point to message ! 25181: movl $num01,kvabe # set abend flag ! 25182: jsb prtnl # skip to new line ! 25183: jmp stopr # jump to pack up ! 25184: #page ! 25185: # ! 25186: # SYSTU -- PRINT /TIME UP/ AND TERMINATE ! 25187: # ! 25188: systu: #rtn ! 25189: movl $endtu,r9 # point to message ! 25190: movl strtu,r6 # get chars /tu/ ! 25191: movl r6,kvcod # put in kvcod ! 25192: movl timup,r6 # check state of timeup switch ! 25193: movl sp,timup # set switch ! 25194: tstl r6 # stop run if already set ! 25195: beqlu 0f ! 25196: jmp stopr ! 25197: 0: ! 25198: jmp er_245 # translation/execution time expired ! 25199: #title s p i t b o l -- stack overflow section ! 25200: # ! 25201: # CONTROL COMES HERE IF THE MAIN STACK OVERFLOWS ! 25202: # ! 25203: er_001: movzwl $1,r6 ! 25204: jmp error ! 25205: er_002: movzwl $2,r6 ! 25206: jmp error ! 25207: er_003: movzwl $3,r6 ! 25208: jmp error ! 25209: er_004: movzwl $4,r6 ! 25210: jmp error ! 25211: er_005: movzwl $5,r6 ! 25212: jmp error ! 25213: er_006: movzwl $6,r6 ! 25214: jmp error ! 25215: er_007: movzwl $7,r6 ! 25216: jmp error ! 25217: er_008: movzwl $8,r6 ! 25218: jmp error ! 25219: er_009: movzwl $9,r6 ! 25220: jmp error ! 25221: er_010: movzwl $10,r6 ! 25222: jmp error ! 25223: er_011: movzwl $11,r6 ! 25224: jmp error ! 25225: er_012: movzwl $12,r6 ! 25226: jmp error ! 25227: er_013: movzwl $13,r6 ! 25228: jmp error ! 25229: er_014: movzwl $14,r6 ! 25230: jmp error ! 25231: er_015: movzwl $15,r6 ! 25232: jmp error ! 25233: er_016: movzwl $16,r6 ! 25234: jmp error ! 25235: er_017: movzwl $17,r6 ! 25236: jmp error ! 25237: er_018: movzwl $18,r6 ! 25238: jmp error ! 25239: er_019: movzwl $19,r6 ! 25240: jmp error ! 25241: er_020: movzwl $20,r6 ! 25242: jmp error ! 25243: er_021: movzwl $21,r6 ! 25244: jmp error ! 25245: er_022: movzwl $22,r6 ! 25246: jmp error ! 25247: er_023: movzwl $23,r6 ! 25248: jmp error ! 25249: er_024: movzwl $24,r6 ! 25250: jmp error ! 25251: er_025: movzwl $25,r6 ! 25252: jmp error ! 25253: er_026: movzwl $26,r6 ! 25254: jmp error ! 25255: er_027: movzwl $27,r6 ! 25256: jmp error ! 25257: er_028: movzwl $28,r6 ! 25258: jmp error ! 25259: er_029: movzwl $29,r6 ! 25260: jmp error ! 25261: er_030: movzwl $30,r6 ! 25262: jmp error ! 25263: er_031: movzwl $31,r6 ! 25264: jmp error ! 25265: er_032: movzwl $32,r6 ! 25266: jmp error ! 25267: er_033: movzwl $33,r6 ! 25268: jmp error ! 25269: er_034: movzwl $34,r6 ! 25270: jmp error ! 25271: er_035: movzwl $35,r6 ! 25272: jmp error ! 25273: er_036: movzwl $36,r6 ! 25274: jmp error ! 25275: er_037: movzwl $37,r6 ! 25276: jmp error ! 25277: er_038: movzwl $38,r6 ! 25278: jmp error ! 25279: er_039: movzwl $39,r6 ! 25280: jmp error ! 25281: er_040: movzwl $40,r6 ! 25282: jmp error ! 25283: er_041: movzwl $41,r6 ! 25284: jmp error ! 25285: er_042: movzwl $42,r6 ! 25286: jmp error ! 25287: er_043: movzwl $43,r6 ! 25288: jmp error ! 25289: er_044: movzwl $44,r6 ! 25290: jmp error ! 25291: er_045: movzwl $45,r6 ! 25292: jmp error ! 25293: er_046: movzwl $46,r6 ! 25294: jmp error ! 25295: er_047: movzwl $47,r6 ! 25296: jmp error ! 25297: er_048: movzwl $48,r6 ! 25298: jmp error ! 25299: er_049: movzwl $49,r6 ! 25300: jmp error ! 25301: er_050: movzwl $50,r6 ! 25302: jmp error ! 25303: er_051: movzwl $51,r6 ! 25304: jmp error ! 25305: er_052: movzwl $52,r6 ! 25306: jmp error ! 25307: er_053: movzwl $53,r6 ! 25308: jmp error ! 25309: er_054: movzwl $54,r6 ! 25310: jmp error ! 25311: er_055: movzwl $55,r6 ! 25312: jmp error ! 25313: er_056: movzwl $56,r6 ! 25314: jmp error ! 25315: er_057: movzwl $57,r6 ! 25316: jmp error ! 25317: er_058: movzwl $58,r6 ! 25318: jmp error ! 25319: er_059: movzwl $59,r6 ! 25320: jmp error ! 25321: er_060: movzwl $60,r6 ! 25322: jmp error ! 25323: er_061: movzwl $61,r6 ! 25324: jmp error ! 25325: er_062: movzwl $62,r6 ! 25326: jmp error ! 25327: er_063: movzwl $63,r6 ! 25328: jmp error ! 25329: er_064: movzwl $64,r6 ! 25330: jmp error ! 25331: er_065: movzwl $65,r6 ! 25332: jmp error ! 25333: er_066: movzwl $66,r6 ! 25334: jmp error ! 25335: er_067: movzwl $67,r6 ! 25336: jmp error ! 25337: er_068: movzwl $68,r6 ! 25338: jmp error ! 25339: er_069: movzwl $69,r6 ! 25340: jmp error ! 25341: er_070: movzwl $70,r6 ! 25342: jmp error ! 25343: er_071: movzwl $71,r6 ! 25344: jmp error ! 25345: er_072: movzwl $72,r6 ! 25346: jmp error ! 25347: er_073: movzwl $73,r6 ! 25348: jmp error ! 25349: er_074: movzwl $74,r6 ! 25350: jmp error ! 25351: er_075: movzwl $75,r6 ! 25352: jmp error ! 25353: er_076: movzwl $76,r6 ! 25354: jmp error ! 25355: er_077: movzwl $77,r6 ! 25356: jmp error ! 25357: er_078: movzwl $78,r6 ! 25358: jmp error ! 25359: er_079: movzwl $79,r6 ! 25360: jmp error ! 25361: er_080: movzwl $80,r6 ! 25362: jmp error ! 25363: er_081: movzwl $81,r6 ! 25364: jmp error ! 25365: er_082: movzwl $82,r6 ! 25366: jmp error ! 25367: er_083: movzwl $83,r6 ! 25368: jmp error ! 25369: er_084: movzwl $84,r6 ! 25370: jmp error ! 25371: er_085: movzwl $85,r6 ! 25372: jmp error ! 25373: er_086: movzwl $86,r6 ! 25374: jmp error ! 25375: er_087: movzwl $87,r6 ! 25376: jmp error ! 25377: er_088: movzwl $88,r6 ! 25378: jmp error ! 25379: er_089: movzwl $89,r6 ! 25380: jmp error ! 25381: er_090: movzwl $90,r6 ! 25382: jmp error ! 25383: er_091: movzwl $91,r6 ! 25384: jmp error ! 25385: er_092: movzwl $92,r6 ! 25386: jmp error ! 25387: er_093: movzwl $93,r6 ! 25388: jmp error ! 25389: er_094: movzwl $94,r6 ! 25390: jmp error ! 25391: er_095: movzwl $95,r6 ! 25392: jmp error ! 25393: er_096: movzwl $96,r6 ! 25394: jmp error ! 25395: er_097: movzwl $97,r6 ! 25396: jmp error ! 25397: er_098: movzwl $98,r6 ! 25398: jmp error ! 25399: er_099: movzwl $99,r6 ! 25400: jmp error ! 25401: er_100: movzwl $100,r6 ! 25402: jmp error ! 25403: er_101: movzwl $101,r6 ! 25404: jmp error ! 25405: er_102: movzwl $102,r6 ! 25406: jmp error ! 25407: er_103: movzwl $103,r6 ! 25408: jmp error ! 25409: er_104: movzwl $104,r6 ! 25410: jmp error ! 25411: er_105: movzwl $105,r6 ! 25412: jmp error ! 25413: er_106: movzwl $106,r6 ! 25414: jmp error ! 25415: er_107: movzwl $107,r6 ! 25416: jmp error ! 25417: er_108: movzwl $108,r6 ! 25418: jmp error ! 25419: er_109: movzwl $109,r6 ! 25420: jmp error ! 25421: er_110: movzwl $110,r6 ! 25422: jmp error ! 25423: er_111: movzwl $111,r6 ! 25424: jmp error ! 25425: er_112: movzwl $112,r6 ! 25426: jmp error ! 25427: er_113: movzwl $113,r6 ! 25428: jmp error ! 25429: er_114: movzwl $114,r6 ! 25430: jmp error ! 25431: er_115: movzwl $115,r6 ! 25432: jmp error ! 25433: er_116: movzwl $116,r6 ! 25434: jmp error ! 25435: er_117: movzwl $117,r6 ! 25436: jmp error ! 25437: er_118: movzwl $118,r6 ! 25438: jmp error ! 25439: er_119: movzwl $119,r6 ! 25440: jmp error ! 25441: er_120: movzwl $120,r6 ! 25442: jmp error ! 25443: er_121: movzwl $121,r6 ! 25444: jmp error ! 25445: er_122: movzwl $122,r6 ! 25446: jmp error ! 25447: er_123: movzwl $123,r6 ! 25448: jmp error ! 25449: er_124: movzwl $124,r6 ! 25450: jmp error ! 25451: er_125: movzwl $125,r6 ! 25452: jmp error ! 25453: er_126: movzwl $126,r6 ! 25454: jmp error ! 25455: er_127: movzwl $127,r6 ! 25456: jmp error ! 25457: er_128: movzwl $128,r6 ! 25458: jmp error ! 25459: er_129: movzwl $129,r6 ! 25460: jmp error ! 25461: er_130: movzwl $130,r6 ! 25462: jmp error ! 25463: er_131: movzwl $131,r6 ! 25464: jmp error ! 25465: er_132: movzwl $132,r6 ! 25466: jmp error ! 25467: er_133: movzwl $133,r6 ! 25468: jmp error ! 25469: er_134: movzwl $134,r6 ! 25470: jmp error ! 25471: er_135: movzwl $135,r6 ! 25472: jmp error ! 25473: er_136: movzwl $136,r6 ! 25474: jmp error ! 25475: er_137: movzwl $137,r6 ! 25476: jmp error ! 25477: er_138: movzwl $138,r6 ! 25478: jmp error ! 25479: er_139: movzwl $139,r6 ! 25480: jmp error ! 25481: er_140: movzwl $140,r6 ! 25482: jmp error ! 25483: er_141: movzwl $141,r6 ! 25484: jmp error ! 25485: er_142: movzwl $142,r6 ! 25486: jmp error ! 25487: er_143: movzwl $143,r6 ! 25488: jmp error ! 25489: er_144: movzwl $144,r6 ! 25490: jmp error ! 25491: er_145: movzwl $145,r6 ! 25492: jmp error ! 25493: er_146: movzwl $146,r6 ! 25494: jmp error ! 25495: er_147: movzwl $147,r6 ! 25496: jmp error ! 25497: er_148: movzwl $148,r6 ! 25498: jmp error ! 25499: er_149: movzwl $149,r6 ! 25500: jmp error ! 25501: er_150: movzwl $150,r6 ! 25502: jmp error ! 25503: er_151: movzwl $151,r6 ! 25504: jmp error ! 25505: er_152: movzwl $152,r6 ! 25506: jmp error ! 25507: er_153: movzwl $153,r6 ! 25508: jmp error ! 25509: er_154: movzwl $154,r6 ! 25510: jmp error ! 25511: er_155: movzwl $155,r6 ! 25512: jmp error ! 25513: er_156: movzwl $156,r6 ! 25514: jmp error ! 25515: er_157: movzwl $157,r6 ! 25516: jmp error ! 25517: er_158: movzwl $158,r6 ! 25518: jmp error ! 25519: er_159: movzwl $159,r6 ! 25520: jmp error ! 25521: er_160: movzwl $160,r6 ! 25522: jmp error ! 25523: er_161: movzwl $161,r6 ! 25524: jmp error ! 25525: er_162: movzwl $162,r6 ! 25526: jmp error ! 25527: er_163: movzwl $163,r6 ! 25528: jmp error ! 25529: er_164: movzwl $164,r6 ! 25530: jmp error ! 25531: er_165: movzwl $165,r6 ! 25532: jmp error ! 25533: er_166: movzwl $166,r6 ! 25534: jmp error ! 25535: er_167: movzwl $167,r6 ! 25536: jmp error ! 25537: er_168: movzwl $168,r6 ! 25538: jmp error ! 25539: er_169: movzwl $169,r6 ! 25540: jmp error ! 25541: er_170: movzwl $170,r6 ! 25542: jmp error ! 25543: er_171: movzwl $171,r6 ! 25544: jmp error ! 25545: er_172: movzwl $172,r6 ! 25546: jmp error ! 25547: er_173: movzwl $173,r6 ! 25548: jmp error ! 25549: er_174: movzwl $174,r6 ! 25550: jmp error ! 25551: er_175: movzwl $175,r6 ! 25552: jmp error ! 25553: er_176: movzwl $176,r6 ! 25554: jmp error ! 25555: er_177: movzwl $177,r6 ! 25556: jmp error ! 25557: er_178: movzwl $178,r6 ! 25558: jmp error ! 25559: er_179: movzwl $179,r6 ! 25560: jmp error ! 25561: er_180: movzwl $180,r6 ! 25562: jmp error ! 25563: er_181: movzwl $181,r6 ! 25564: jmp error ! 25565: er_182: movzwl $182,r6 ! 25566: jmp error ! 25567: er_183: movzwl $183,r6 ! 25568: jmp error ! 25569: er_184: movzwl $184,r6 ! 25570: jmp error ! 25571: er_185: movzwl $185,r6 ! 25572: jmp error ! 25573: er_186: movzwl $186,r6 ! 25574: jmp error ! 25575: er_187: movzwl $187,r6 ! 25576: jmp error ! 25577: er_188: movzwl $188,r6 ! 25578: jmp error ! 25579: er_189: movzwl $189,r6 ! 25580: jmp error ! 25581: er_190: movzwl $190,r6 ! 25582: jmp error ! 25583: er_191: movzwl $191,r6 ! 25584: jmp error ! 25585: er_192: movzwl $192,r6 ! 25586: jmp error ! 25587: er_193: movzwl $193,r6 ! 25588: jmp error ! 25589: er_194: movzwl $194,r6 ! 25590: jmp error ! 25591: er_195: movzwl $195,r6 ! 25592: jmp error ! 25593: er_196: movzwl $196,r6 ! 25594: jmp error ! 25595: er_197: movzwl $197,r6 ! 25596: jmp error ! 25597: er_198: movzwl $198,r6 ! 25598: jmp error ! 25599: er_199: movzwl $199,r6 ! 25600: jmp error ! 25601: er_200: movzwl $200,r6 ! 25602: jmp error ! 25603: er_201: movzwl $201,r6 ! 25604: jmp error ! 25605: er_202: movzwl $202,r6 ! 25606: jmp error ! 25607: er_203: movzwl $203,r6 ! 25608: jmp error ! 25609: er_204: movzwl $204,r6 ! 25610: jmp error ! 25611: er_205: movzwl $205,r6 ! 25612: jmp error ! 25613: er_206: movzwl $206,r6 ! 25614: jmp error ! 25615: er_207: movzwl $207,r6 ! 25616: jmp error ! 25617: er_208: movzwl $208,r6 ! 25618: jmp error ! 25619: er_209: movzwl $209,r6 ! 25620: jmp error ! 25621: er_210: movzwl $210,r6 ! 25622: jmp error ! 25623: er_211: movzwl $211,r6 ! 25624: jmp error ! 25625: er_212: movzwl $212,r6 ! 25626: jmp error ! 25627: er_213: movzwl $213,r6 ! 25628: jmp error ! 25629: er_214: movzwl $214,r6 ! 25630: jmp error ! 25631: er_215: movzwl $215,r6 ! 25632: jmp error ! 25633: er_216: movzwl $216,r6 ! 25634: jmp error ! 25635: er_217: movzwl $217,r6 ! 25636: jmp error ! 25637: er_218: movzwl $218,r6 ! 25638: jmp error ! 25639: er_219: movzwl $219,r6 ! 25640: jmp error ! 25641: er_220: movzwl $220,r6 ! 25642: jmp error ! 25643: er_221: movzwl $221,r6 ! 25644: jmp error ! 25645: er_222: movzwl $222,r6 ! 25646: jmp error ! 25647: er_223: movzwl $223,r6 ! 25648: jmp error ! 25649: er_224: movzwl $224,r6 ! 25650: jmp error ! 25651: er_225: movzwl $225,r6 ! 25652: jmp error ! 25653: er_226: movzwl $226,r6 ! 25654: jmp error ! 25655: er_227: movzwl $227,r6 ! 25656: jmp error ! 25657: er_228: movzwl $228,r6 ! 25658: jmp error ! 25659: er_229: movzwl $229,r6 ! 25660: jmp error ! 25661: er_230: movzwl $230,r6 ! 25662: jmp error ! 25663: er_231: movzwl $231,r6 ! 25664: jmp error ! 25665: er_232: movzwl $232,r6 ! 25666: jmp error ! 25667: er_233: movzwl $233,r6 ! 25668: jmp error ! 25669: er_234: movzwl $234,r6 ! 25670: jmp error ! 25671: er_235: movzwl $235,r6 ! 25672: jmp error ! 25673: er_236: movzwl $236,r6 ! 25674: jmp error ! 25675: er_237: movzwl $237,r6 ! 25676: jmp error ! 25677: er_238: movzwl $238,r6 ! 25678: jmp error ! 25679: er_239: movzwl $239,r6 ! 25680: jmp error ! 25681: er_240: movzwl $240,r6 ! 25682: jmp error ! 25683: er_241: movzwl $241,r6 ! 25684: jmp error ! 25685: er_242: movzwl $242,r6 ! 25686: jmp error ! 25687: er_243: movzwl $243,r6 ! 25688: jmp error ! 25689: er_244: movzwl $244,r6 ! 25690: jmp error ! 25691: er_245: movzwl $245,r6 ! 25692: jmp error ! 25693: er_246: movzwl $246,r6 ! 25694: jmp error ! 25695: er_247: movzwl $247,r6 ! 25696: jmp error ! 25697: er_248: movzwl $248,r6 ! 25698: jmp error ! 25699: er_249: movzwl $249,r6 ! 25700: jmp error ! 25701: er_250: movzwl $250,r6 ! 25702: jmp error ! 25703: er_251: movzwl $251,r6 ! 25704: jmp error ! 25705: er_252: movzwl $252,r6 ! 25706: jmp error ! 25707: er_253: movzwl $253,r6 ! 25708: jmp error ! 25709: er_254: movzwl $254,r6 ! 25710: jmp error ! 25711: er_255: movzwl $255,r6 ! 25712: jmp error ! 25713: er_256: movzwl $256,r6 ! 25714: jmp error ! 25715: er_257: movzwl $257,r6 ! 25716: jmp error ! 25717: er_258: movzwl $258,r6 ! 25718: jmp error ! 25719: er_259: movzwl $259,r6 ! 25720: jmp error ! 25721: er_260: movzwl $260,r6 ! 25722: jmp error ! 25723: er_261: movzwl $261,r6 ! 25724: jmp error ! 25725: er_262: movzwl $262,r6 ! 25726: jmp error ! 25727: er_263: movzwl $263,r6 ! 25728: jmp error ! 25729: er_264: movzwl $264,r6 ! 25730: jmp error ! 25731: er_265: movzwl $265,r6 ! 25732: jmp error ! 25733: er_266: movzwl $266,r6 ! 25734: jmp error ! 25735: er_267: movzwl $267,r6 ! 25736: jmp error ! 25737: er_268: movzwl $268,r6 ! 25738: jmp error ! 25739: er_269: movzwl $269,r6 ! 25740: jmp error ! 25741: er_270: movzwl $270,r6 ! 25742: jmp error ! 25743: er_271: movzwl $271,r6 ! 25744: jmp error ! 25745: er_272: movzwl $272,r6 ! 25746: jmp error ! 25747: er_273: movzwl $273,r6 ! 25748: jmp error ! 25749: er_274: movzwl $274,r6 ! 25750: jmp error ! 25751: er_275: movzwl $275,r6 ! 25752: jmp error ! 25753: er_276: movzwl $276,r6 ! 25754: jmp error ! 25755: er_277: movzwl $277,r6 ! 25756: jmp error ! 25757: er_278: movzwl $278,r6 ! 25758: jmp error ! 25759: er_279: movzwl $279,r6 ! 25760: jmp error ! 25761: er_280: movzwl $280,r6 ! 25762: jmp error ! 25763: er_281: movzwl $281,r6 ! 25764: jmp error ! 25765: er_282: movzwl $282,r6 ! 25766: jmp error ! 25767: er_283: movzwl $283,r6 ! 25768: jmp error ! 25769: er_284: movzwl $284,r6 ! 25770: jmp error ! 25771: er_285: movzwl $285,r6 ! 25772: jmp error ! 25773: er_286: movzwl $286,r6 ! 25774: jmp error ! 25775: er_287: movzwl $287,r6 ! 25776: jmp error ! 25777: er_288: movzwl $288,r6 ! 25778: jmp error ! 25779: er_289: movzwl $289,r6 ! 25780: jmp error ! 25781: er_290: movzwl $290,r6 ! 25782: jmp error ! 25783: er_291: movzwl $291,r6 ! 25784: jmp error ! 25785: er_292: movzwl $292,r6 ! 25786: jmp error ! 25787: er_293: movzwl $293,r6 ! 25788: jmp error ! 25789: er_294: movzwl $294,r6 ! 25790: jmp error ! 25791: er_295: movzwl $295,r6 ! 25792: jmp error ! 25793: er_296: movzwl $296,r6 ! 25794: jmp error ! 25795: er_297: movzwl $297,r6 ! 25796: jmp error ! 25797: .globl sec05 ! 25798: sec05: ! 25799: #sec # start of stack overflow section ! 25800: # ! 25801: incl errft # fatal error ! 25802: movl flptr,sp # pop stack to avoid more fails ! 25803: tstl gbcfl # jump if garbage collecting ! 25804: bnequ stak1 ! 25805: jmp er_246 # stack overflow ! 25806: # ! 25807: # NO CHANCE OF RECOVERY IN MID GARBAGE COLLECTION ! 25808: # ! 25809: stak1: movl $endso,r9 # point to message ! 25810: clrl kvdmp # memory is undumpable ! 25811: jmp stopr # give up ! 25812: #title s p i t b o l -- error section ! 25813: # ! 25814: # THIS SECTION OF CODE IS ENTERED WHENEVER A PROCEDURE ! 25815: # RETURN VIA AN ERR PARAMETER OR AN ERB OPCODE IS OBEYED. ! 25816: # ! 25817: # (WA) IS THE ERROR CODE ! 25818: # ! 25819: # THE GLOBAL VARIABLE STAGE INDICATES THE POINT AT WHICH ! 25820: # THE ERROR OCCURED AS FOLLOWS. ! 25821: # ! 25822: # STAGE=STGIC ERROR DURING INITIAL COMPILE ! 25823: # ! 25824: # STAGE=STGXC ERROR DURING COMPILE AT EXECUTE ! 25825: # TIME (CODE, CONVERT FUNCTION CALLS) ! 25826: # ! 25827: # STAGE=STGEV ERROR DURING COMPILATION OF ! 25828: # EXPRESSION AT EXECUTION TIME ! 25829: # (EVAL, CONVERT FUNCTION CALL). ! 25830: # ! 25831: # STAGE=STGXT ERROR AT EXECUTE TIME. COMPILER ! 25832: # NOT ACTIVE. ! 25833: # ! 25834: # STAGE=STGCE ERROR DURING INITIAL COMPILE AFTER ! 25835: # SCANNING OUT THE END LINE. ! 25836: # ! 25837: # STAGE=STGXE ERROR DURING COMPILE AT EXECUTE ! 25838: # TIME AFTER SCANNING END LINE. ! 25839: # ! 25840: # STAGE=STGEE ERROR DURING EXPRESSION EVALUATION ! 25841: # ! 25842: #sec # start of error section ! 25843: # ! 25844: error: cmpl r$cim,$cmlab # jump if error in scanning label ! 25845: bnequ 0f ! 25846: jmp cmple ! 25847: 0: ! 25848: movl r6,kvert # save error code ! 25849: clrl scnrs # reset rescan switch for scane ! 25850: clrl scngo # reset goto switch for scane ! 25851: movl stage,r9 # load current stage ! 25852: casel r9,$0,$stgno # jump to appropriate error circuit ! 25853: 5: ! 25854: .word err01-5b # initial compile ! 25855: .word err04-5b # execute time compile ! 25856: .word err04-5b # eval compiling expr. ! 25857: .word err05-5b # execute time ! 25858: .word err01-5b # compile - after end ! 25859: .word err04-5b # xeq compile-past end ! 25860: .word err04-5b # eval evaluating expr ! 25861: #esw # end switch on error type ! 25862: #page ! 25863: # ! 25864: # ERROR DURING INITIAL COMPILE ! 25865: # ! 25866: # THE ERROR MESSAGE IS PRINTED AS PART OF THE COMPILER ! 25867: # OUTPUT. THIS PRINTOUT INCLUDES THE OFFENDING LINE (IF NOT ! 25868: # PRINTED ALREADY) AND AN ERROR FLAG UNDER THE APPROPRIATE ! 25869: # COLUMN AS INDICATED BY SCNSE UNLESS SCNSE IS SET TO ZERO. ! 25870: # ! 25871: # AFTER PRINTING THE MESSAGE, THE GENERATED CODE IS ! 25872: # MODIFIED TO AN ERROR CALL AND CONTROL IS RETURNED TO ! 25873: # THE CMPIL PROCEDURE AFTER RESETTING THE STACK POINTER. ! 25874: # ! 25875: # IF THE ERROR OCCURS AFTER THE END LINE, CONTROL RETURNS ! 25876: # IN A SLIGHTLY DIFFERENT MANNER TO ENSURE PROPER CLEANUP. ! 25877: # ! 25878: err01: movl cmpxs,sp # reset stack pointer ! 25879: #ssl cmpss # restore s-r stack ptr for cmpil ! 25880: tstl errsp # jump if error suppress flag set ! 25881: beqlu 0f ! 25882: jmp err03 ! 25883: 0: ! 25884: movl erich,erlst # set flag for listr ! 25885: jsb listr # list line ! 25886: jsb prtis # terminate listing ! 25887: clrl erlst # clear listr flag ! 25888: movl scnse,r6 # load scan element offset ! 25889: tstl r6 # skip if not set ! 25890: beqlu err02 ! 25891: movl r6,r7 # loop counter ! 25892: incl r6 # increase for ch$ex ! 25893: jsb alocs # string block for error flag ! 25894: movl r9,r6 # remember string ptr ! 25895: movab cfp$f(r9),r9 # ready for character storing ! 25896: movl r$cim,r10 # point to bad statement ! 25897: movab cfp$f(r10),r10 # ready to get chars ! 25898: # ! 25899: # LOOP TO REPLACE ALL CHARS BUT TABS BY BLANKS ! 25900: # ! 25901: erra1: movzbl (r10)+,r8 # get next char ! 25902: cmpl r8,$ch$ht # skip if tab ! 25903: beqlu erra2 ! 25904: movl $ch$bl,r8 # get a blank ! 25905: #page ! 25906: # ! 25907: # MERGE TO STORE BLANK OR TAB IN ERROR LINE ! 25908: # ! 25909: erra2: movb r8,(r9)+ # store char ! 25910: sobgtr r7,erra1 # loop ! 25911: movl $ch$ex,r10 # exclamation mark ! 25912: movb r10,(r9) # store at end of error line ! 25913: #csc r9 # end of sch loop ! 25914: movl $stnpd,profs # allow for statement number ! 25915: movl r6,r9 # point to error line ! 25916: jsb prtst # print error line ! 25917: # ! 25918: # HERE AFTER PLACING ERROR FLAG AS REQUIRED ! 25919: # ! 25920: err02: jsb ermsg # generate flag and error message ! 25921: addl2 $num03,lstlc # bump page ctr for blank, error, blk ! 25922: clrl r9 # in case of fatal error ! 25923: cmpl errft,$num03 # pack up if several fatals ! 25924: blssu 0f ! 25925: jmp stopr ! 25926: 0: ! 25927: # ! 25928: # COUNT ERROR, INHIBIT EXECUTION IF REQUIRED ! 25929: # ! 25930: incl cmerc # bump error count ! 25931: addl2 cswer,noxeq # inhibit xeq if -noerrors ! 25932: cmpl stage,$stgic # special return if after end line ! 25933: beqlu 0f ! 25934: jmp cmp10 ! 25935: 0: ! 25936: #page ! 25937: # ! 25938: # LOOP TO SCAN TO END OF STATEMENT ! 25939: # ! 25940: err03: movl r$cim,r9 # point to start of image ! 25941: movab cfp$f(r9),r9 # point to first char ! 25942: movzbl (r9),r9 # get first char ! 25943: cmpl r9,$ch$mn # jump if error in control card ! 25944: bnequ 0f ! 25945: jmp cmpce ! 25946: 0: ! 25947: clrl scnrs # clear rescan flag ! 25948: movl sp,errsp # set error suppress flag ! 25949: jsb scane # scan next element ! 25950: cmpl r10,$t$smc # loop back if not statement end ! 25951: beqlu 0f ! 25952: jmp err03 ! 25953: 0: ! 25954: clrl errsp # clear error suppress flag ! 25955: # ! 25956: # GENERATE ERROR CALL IN CODE AND RETURN TO CMPIL ! 25957: # ! 25958: movl $4*cdcod,cwcof # reset offset in ccblk ! 25959: movl $ocer$,r6 # load compile error call ! 25960: jsb cdwrd # generate it ! 25961: movl cwcof,4*cmsoc(sp)# set success fill in offset ! 25962: movl sp,4*cmffc(sp) # set failure fill in flag ! 25963: jsb cdwrd # generate succ. fill in word ! 25964: jmp cmpse # merge to generate error as cdfal ! 25965: # ! 25966: # ERROR DURING EXECUTE TIME COMPILE OR EXPRESSION EVALUATIO ! 25967: # ! 25968: # EXECUTE TIME COMPILATION IS INITIATED THROUGH GTCOD OR ! 25969: # GTEXP WHICH ARE CALLED BY COMPILE, CODE OR EVAL. ! 25970: # BEFORE CAUSING STATEMENT FAILURE THROUGH EXFAL IT IS ! 25971: # HELPFUL TO SET KEYWORD ERRTEXT AND FOR GENERALITY ! 25972: # THESE ERRORS MAY BE HANDLED BY THE SETEXIT MECHANISM. ! 25973: # ! 25974: err04: clrl r$ccb # forget garbage code block ! 25975: #ssl iniss # restore main prog s-r stack ptr ! 25976: jsb ertex # get fail message text ! 25977: subl2 $4,sp # ensure stack ok on loop start ! 25978: # ! 25979: # POP STACK UNTIL FIND FLPTR FOR MOST DEEPLY NESTED PROG. ! 25980: # DEFINED FUNCTION CALL OR CALL OF EVAL / CODE. ! 25981: # ! 25982: erra4: addl2 $4,sp # pop stack ! 25983: cmpl sp,flprt # jump if prog defined fn call found ! 25984: beqlu errc4 ! 25985: cmpl sp,gtcef # loop if not eval or code call yet ! 25986: bnequ erra4 ! 25987: movl $stgxt,stage # re-set stage for execute ! 25988: movl r$gtc,r$cod # recover code ptr ! 25989: movl sp,flptr # restore fail pointer ! 25990: clrl r$cim # forget possible image ! 25991: # ! 25992: # TEST ERRLIMIT ! 25993: # ! 25994: errb4: tstl kverl # jump if errlimit non-zero ! 25995: bnequ err07 ! 25996: jmp exfal # fail ! 25997: # ! 25998: # RETURN FROM PROG. DEFINED FUNCTION IS OUTSTANDING ! 25999: # ! 26000: errc4: movl flptr,sp # restore stack from flptr ! 26001: jmp errb4 # merge ! 26002: #page ! 26003: # ! 26004: # ERROR AT EXECUTE TIME. ! 26005: # ! 26006: # THE ACTION TAKEN ON AN ERROR IS AS FOLLOWS. ! 26007: # ! 26008: # IF ERRLIMIT KEYWORD IS ZERO, AN ABORT IS SIGNALLED, ! 26009: # SEE CODING FOR SYSTEM LABEL ABORT AT L$ABO. ! 26010: # ! 26011: # OTHERWISE, ERRLIMIT IS DECREMENTED AND AN ERRTYPE TRACE ! 26012: # GENERATED IF REQUIRED. CONTROL RETURNS EITHER VIA A JUMP ! 26013: # TO CONTINUE (TO TAKE THE FAILURE EXIT) OR A SPECIFIED ! 26014: # SETEXIT TRAP IS EXECUTED AND CONTROL PASSES TO THE TRAP. ! 26015: # IF 3 OR MORE FATAL ERRORS OCCUR AN ABORT IS SIGNALLED ! 26016: # REGARDLESS OF ERRLIMIT AND SETEXIT - LOOPING IS ALL TOO ! 26017: # PROBABLE OTHERWISE. FATAL ERRORS INCLUDE STACK OVERFLOW ! 26018: # AND EXCEEDING STLIMIT. ! 26019: # ! 26020: err05: #ssl iniss # restore main prog s-r stack ptr ! 26021: tstl dmvch # jump if in mid-dump ! 26022: bnequ err08 ! 26023: # ! 26024: # MERGE HERE FROM ERR08 ! 26025: # ! 26026: err06: tstl kverl # abort if errlimit is zero ! 26027: bnequ 0f ! 26028: jmp labo1 ! 26029: 0: ! 26030: jsb ertex # get fail message text ! 26031: # ! 26032: # MERGE FROM ERR04 ! 26033: # ! 26034: err07: cmpl errft,$num03 # abort if too many fatal errors ! 26035: blssu 0f ! 26036: jmp labo1 ! 26037: 0: ! 26038: decl kverl # decrement errlimit ! 26039: movl r$ert,r10 # load errtype trace pointer ! 26040: jsb ktrex # generate errtype trace if required ! 26041: movl r$cod,r$cnt # set cdblk ptr for continuation ! 26042: movl flptr,r9 # set ptr to failure offset ! 26043: movl (r9),stxof # save failure offset for continue ! 26044: movl r$sxc,r9 # load setexit cdblk pointer ! 26045: tstl r9 # continue if no setexit trap ! 26046: bnequ 0f ! 26047: jmp lcnt1 ! 26048: 0: ! 26049: clrl r$sxc # else reset trap ! 26050: movl $nulls,stxvr # reset setexit arg to null ! 26051: movl (r9),r10 # load ptr to code block routine ! 26052: movl r10,r11 # execute first trap statement ! 26053: jmp (r11) ! 26054: # ! 26055: # INTERRUPTED PARTLY THROUGH A DUMP WHILST STORE IS IN A ! 26056: # MESS SO DO A TIDY UP OPERATION. SEE DUMPR FOR DETAILS. ! 26057: # ! 26058: err08: movl dmvch,r9 # chain head for affected vrblks ! 26059: tstl r9 # done if zero ! 26060: beqlu err06 ! 26061: movl (r9),dmvch # set next link as chain head ! 26062: jsb setvr # restore vrget field ! 26063: jmp err08 # loop through chain ! 26064: #title s p i t b o l -- here endeth the code ! 26065: # ! 26066: # END OF ASSEMBLY ! 26067: # ! 26068: #end # end macro-spitbol assembly
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.