compilers/algol/algol60fs.imp

!
! ALGOL 1.5 DATED NOV 76
! 1) CONTAINS CORRECTION TO GIVE ERROR MESSAGE FOR THE
! %FOR..%DO %BEGIN...%END %ELSE %BEGIN CONSTRUCT WHICH IS INVALID
! 2) CHOPS RATHER THAN FAULTING LONG STRING CONSTANTS
! 3) CHECKS FOR BEGINS IN SYNTACTICALLY INCORRECT STATEMENTS TO
! REDUCE THE ERRONEOUS FAULT MESSAGES WHEN LEVELS MISMATCH
! 4) CONTAINS THE BINARY IO ROUTINE NAMES
! 5) STORES PLT DESCRIPTOR CORRECTLY IN EXTERNAL PROCEDURES
!
! ALGOL 1.6 DATED 1ST DEC 76
! 1) CONTAINS CORRECTION TO READ1900 (MISTYPED AS INTEGERPROC)
! 2) CONTAINS CORRECT SPACE ALLOCATION SO THAT STORED VALUE
! OF STACKFRONT IN PROCEDURES IS NOT CORRUPTED
! 3) USES SYTEMROUTINE STOP TO STOP
! 4) AVOIDS TRYING TO ADD ACC INTO B
!
! ALGOL 1.7 DATED 1ST JAN 77
! 1) HAS INCREASED SPACE IN EXPOP FOR TEMPORARY STACKED OPERANDS
! 2) REMOVES ABORT IN GOTOLAB FOR SWITCHES WITH NO LOCAL LABELS
! 3) AVOIDS STACK TWIST IF B&ACC CLAIMED THEN A MULTI DIMENSION
! ARRAY ELEMENT IF FETCHED
!
! ALGOL 1.8 DATED 1ST FEB 77
! 1) CHANGE TO DEAL WITH ARRAYS WITH CONSTANT BOUNDS WHOSE SIZE
! IS >X1FFFF BYTES.
! 2) CHANGED TO ALLOW THE UNDOCUMENTED BUT FREQUENT '**' FOR **
! 3) CHANGE TO GET LEVELS RIGHT IN SEPERATELY COMPILED PROCEDURES
!
! ALGOL 1.9 DATED 1ST MARCH 77
! 1) CONTAINS CORRECTION TO BUILT IN FN CODE
! 2) RELAXES THE CHECK ON FORMAL PROCEDURES TO ALLOW CROSS LANGUAGE
! PROCEDURE PASSING (AS WELL AS CROSS CALLING)
! 3) AVOIDS CORRUPTING LINE NO OCCAISIONALLY AFTER PARAM NOT DESTN
! 4) CHANGES DA&SQ RTS TO SYSTEM ROUTINES AND ADDS RWNDSQ
!
! ALGOL 1.10 DATED 7TH MARCH 77
! 1) CONTAINS CHECK ON PARAMETERS PASSED TO SEPARATELY COMPILED PROCS
! 2) CONTAINS A %PROGRAM (NAME) STATEMENT TO REDEFINE S#GO
! 3) HAS CHANGES TO DTABLE TO PASS NAME PARAMETERS FOR NDIAGS
! 4) HAS PARM FREE FORMAT TO ALLOW TEXT NOT SEQUENCE NOS IN 72-80
! 5) HAS EXTRA CODE IN MAIN PROGRAM ENTRY SEQ TO ALLOW FOR EXTRA
! PARAMETER ON STACK IN K STANDALONE
! 6) CONTAINS PARTIAL KEYWORD VALIDATION IN LEXICAL SCAN TO AID
! RECOVERY FOR UNMATCHED SINGLE QUOTES
! 7) USES BOUNDED (L=1) DESCRIPTORS FOR PASSING SCALARS BY NAME
! IN PLACE OF BOUND INHIBITED (L=0) DESCRIPTORS. [FOR F1]
!
! ALGOL 2.0 DATED 1ST MAY 77
! THIS HAS NO CHANGES BEING 1.10 LINKED WITH OMF PRODUCING LPUT
!
! ALGOL 2.1 DATED 1ST JUNE 77
! 1) HAS CORRECTION TO CALL THUNKS FOR ACCESSING MULTI-DIMENSION
! ARRAYS WITH ESCAPE SUBROUTINES AS PARAMETERS.(J.JAMIESONS' FLT) !
! 2) HAS EDITING CORRECTION TO CHANGES FOR 1.10.7(CALL THUNKS)
! 3) HAS INCHAR,OUTCHAR CLOSESTREAM &PAPERTHROW ADDED
! 4) HAS ALL INTINSICS TAGGED WITH S#(=ICL9CE)
! 5) HAS THE PARAMETERS OF FAULT CHANGED AS PER ALGOL 60M AND THE
! THE REFERENCE NAME CHANGED T0 "AFAULT" TO AVOID CONFUSION
! 6) HAS CPUTIME & NCODE CHANGED TO SYSTEM ROUTINE
! 7) HAS TOP BIT SET IN AREA WHEN DEFINING PRINCIPAL ENTRYPOINT
! 8) HAS PASSING CONSTANTS DIRECTLY AS NAME PARAMETERS RESTRICTED
! TO PARM(OPT) COMPILATIONS TO GET PARAM NOT DESTINATION.
!
! ALGOL 2.2 DATED 1ST AUGUST 77
! 1) CHANGES TO SW(9) OF CSS TO FAULT DECLNS AFTER DUMMY STMNT
! 2) CHANGES TO BIP(1005) TO CHECK FOR %BEGIN & %END IN COMMENTS
! AND UPDATE LINE SO STMNT NO STAYS IN STEP WITH THOSE NUMBERS
! ASSIGNED(ACTUALLY WRONGLY!) BY THE LEXICAL SCANNER.
! 3) CHANGES TO DOWN LIST TO GIVE CORRECT STMNT NOS WHEN FAULTING
! INCONSISTENT EXTERNAL PROCEDURE HEADINGS
! 4) OMITS IRRELEVANT ERROR ROUTINES WHEN COMPILING WITHOUT FULL CHKS
! 5) HAS MINOR CHANGES TO 'FOR' STMNT TO IMPROVE CODE WHEN FINAL
! VALUE IS SCALAR PASSED BY NAME
! 6) HAS CHANGES TO REDUCE UNNECESSARY AUX STACK SAVING WHEN
! PASS 2 INDICATES NO LABEL OR SWITCH PARAMETERS SO THERE CAN
! BE NO EXPECTED JUMPING OUT OF BLOCKS
! 7) HAS CHANGE FOR JOBBER MODE SO THAT PARM STACK IS NOT NOT
! ASSUMED WHEN SOURCE FILE SIZE IS NOT KNOWN
! 8) HAS CHANGE TO FAULT TO ALLOW FOR BEGIN IN SYNTAXED STMNT WITHOUT
! GETTING REMAINING LINE NOS ONE OUT
! 9) HAS CHANGE TO REAL**REAL SUBROUTINE TO PREVENT OVERFLOW WHEN
! Y IS A SMALL NEGATIVE INTEGER
! 10)HAS ODD ALIGNMENT OF STACKFRAMES READY FOR PRECALL
! 11)INTRODUCES FN PTROFFSET TO PAVE THE WAY FOR CONTRACTION OF
! THE SIZE OF THE DISPLAY
! 12)CHANGES THE TABLE CSNAME TO ALLOW SUBSTITUTION PARAMETERS
! TO BE PASSED TO READ SYMBOL(ETC)
! 13)CHANGES TO THE STORING OF STRINGS IN WORKFILE TO SAVE SPACE
! 14)CHANGES TO RESET STACK TO STOP RESETTING DIAGPOINTER WITH
! ITS CURRENT VALUE WHEN JUMPING OUT OF A FOR BLOCK
! 15)ADDS A SMALL OPTIMISATION IN ROUTINE CSTMNT TO AVOID JUMPING
! AROUND A ONE INSTRUCTION JUMP IN 'IF'...'THEN' 'GOTO' L
! ALGOL 3.0 DATED NOV 77
! 1) HAS CHANGES FOR ALGOL60M AS PER CHANGE PROPOSAL
! 2) HAS CHANGES TO ALLOW STRINGNAME PARAMETERS TO CODE
! 3) HAS CORRECTION TO GIVE CORRECT LINE NO WHEN A RUN TIME FAULT
! OCCURRS DURING EVALUATION OF AN ARRAY BOUND PAIR
! 4) HAS CHANGE TO STOP FAULT 25 WHEN FOR VARIABLE NOT SET
! 5) HAS CORRECTION IN DECLARE ARRAY TO AVOID MISSING OUT 2ND ELEMNT
! WHEN SCANNING FOR PARAMETRIC ARRAYS
! 6) HAS CHANGE TO REXP TO AVOID CORRUPTING B WHEN GOING OFF
! TO THE LOG-EXP SUBROUTINE
! 7) HAS CHANGE IN CEND TO PUT ARRAYS IN DIAG TABLES
! 8) HAS ON CONDITION IN ROUTINE CONST
! 9) ALLOWS @ AS ALT TO & IN CONST AS PER ICL MANUAL
!
! ALGOL 3.1 DATED MAR78
! 1) TRAPS OVERFLOW IN CONST WITHOUT AN "%ON %EVENT"
! 2) REMOVES FAULT 202 FROMCUI AS THIS CASE CAN ARISE WITH
! A BIZARRELY ERRONEOUS PARAMETER LIST
! 3) TAKES MORE CARE IN RHEAD AGAINST DUPLICATE PROCEDURE BODIES
!
! ALGOL 4.0 DATED MAY 78
! 1) HAS NEW INSTRNS AND ASSOCIATED CHANGES
! 2) HAS PROPER METHOD OF FORMING CONSTANT TABLE
! 3) FORMATS ASL ON THE FLY TO MINIMISE OVERHEADS ON SMALL PRGS
! 4) HAS JOBBER MODE BIT AND NEW AREA DETERMINING CODE
! 5) OVERLAYS THE WORKING ARRAYS TO REDUCE W-SET SIZE
! 6) HAS MEND IN CANAME FOR FIXING REAL ARRAY SUBSCRIPTS
! 7) AVOIDS H-W BUG ON 50S & 60S RE JUMPS TO CODE DESCRPTRS
! 8) REMOVES ROUNDING TO WORD BNDR FROM CLAIM AS AS NO ALGOL ARRAYS
! ARE LESS THAN WORD SIZED!
! 9) DEALS WITH BOOLEAN CONTROL VARIABLE IN FOR LOOPS
! 10)ALLOWS INCORRECT NAMES IN FORMAL PROC COMMENT WITHOUT 
! GETTING ARRAY BOUND EXCEEDED
! 11)GIVES CORRECT STSMNT NO WHEN FAILING AFTER %F %THEN %BEGIN
! ...%END %ELSE BUM STATEMENT CONSTRUCT
! 12)ALLOWS @ AS CONSTANT BY ITSELF AS WELL AS AFTER DIGIT
! 13)ACCEPTS THE (EMAS ONLY) OPTION PARM(DYNAMIC)
! ALGOL 50 DATED MARCH 79
! 1) HAS GENERALISATION TO I-RESULTS IN STACK FRAME(RPTYPE=7)
! FOR BETTER USE OF CONSTANTS AND ASSOCIATED CHANGES TO FN RESULTS
! 2) HAS CORECTION TO OPTIMISED **2 CODE TO SAVE ACC WHEN NEEDED
! 3) RELOCATES DESRCIPTORS TO CONSTS IN CTABLE CORRECTLY
! 4) HAS COMPILER ENVIRONMENT BIT AND TITLE SUPPRESSION
! 5) HAS CALL OF SIGNAL 9 (INSTEAD OF 0) IN JOBBER MODE
! 6) HAS EXTRA LINE TO RESET Q AFTER BUM SYNTAX STATEMENT
! 7) BETTER CODE IN COMPARE FOR SYNTAX FAULT AFTER HAVING GONE
! "DOWN" A TEXTUAL LEVEL
!
! ALGOL 51 DATED OCTOBER 79
! 1) CHANGE TO SHORTCUTS IN COMPARE FOR LOWERCASE NAMES
! 2) FORGET OF ACCR IN EXPONETIATION ROUTINE
! 3) CHANGE TO AVOID ABORT ON UNDECLARED FOR VAR
!
! ALGOL 60 DATED JAN 80
! 1) CHANGED ROUTINE PARAMETERS FOR GREATER COMPATABILITY WITH ICL
! 2) ADDITION OF <> FOR # AS COMPARATOR
! 3) ADDITION OF 'EQV' AS ALT TO 'EQUIV' IN BOOLEANS
! 4) RESETIING OF GLACABUF AFTER LAST OF GLA DUMPED IN CASE OF
! ANY LATE GLA PLUGS
! 5) SETING KFORM=0 IN DECLARING OWN ARRAYS
! 6) KEYWORDS ALLOWED IN LOWER CASE
! 7) CORRECTION IN COMPILING LPL FOR FN RESULT OUT OF SCOPE
! 8) RESTRICTING ASL SO 128K AUXSTACK ENOUGH FOR MAXDICT
! 9) SUBDIVISION OF FAILED TO ANALYSE ERRORS
! 10)FAULT 105 MESSAGE ADDED & DOUBLE USE REMOVED
! 11)EBCDIC BIT NOTED &USED FOR STRINGS ETC
! 12) HAS SEPARATOR AFTER BEGIN TO HELP WITH DUMMY STMTS
! 13) CLEARS NAMES AT START OF PASS 3 IN CASE OF PROGS WITH
! NO VARIABLES
! 14) FAULTS MISPLACED SWITCHES AND PROCEDURES
! 15)FURTHER ATTAEMPTS TO FAULT ELSES AFTER END OF FOR BLK
! 16)ADDS TWO NEW ROUTINES PUTARRAY & GETARRAY
! 17) HAS ROUTINE FAULTMK FOR VMEB DISPLAY FEATURE
! 18)HAS LINE INSTEAD OF STATEMENT NUMBERS
! STILL NEEDED:- BETTER CODE FOR REAL FORS WITH CONSTANT STEPS
MAINEP ICL9CEZALGOL;
TRUSTEDPROGRAM 
BEGIN 
CONSTINTEGER YES=1
CONSTINTEGER NO=0
CONSTINTEGER ALLOW CODELIST=YES
CONSTINTEGER INCLUDE HANDCODE=YES
CONSTINTEGER VMEB=NO; ! YES FOR ISSUING TO ICL
INTEGER I, J, K
! PRODUCED FROM ALGOLPS8 BY PSPROG2S ON 07/08/80
CONSTINTEGERARRAY SYMBOL(1300: 2279)= 1305,
 1305, 1001, 1018, 1305, 1313, 1311, 44, 1001, 1018, 999,
 1313, 1000, 1324, 1318, 1001, 1044, 1356, 1320, 1003, 1324,
 40, 1324, 41, 1349, 1343, 201, 198, 1454, 212, 200,
 197, 206, 1010, 1038, 1313, 1011, 1349, 197, 204, 211,
 197, 1324, 1349, 1010, 1038, 1313, 1011, 1349, 1356, 1354,
 1039, 1313, 999, 1356, 1000, 1374, 1365, 1030, 1041, 1010,
 1324, 1011, 1374, 1042, 1372, 40, 1010, 1763, 1011, 1779,
 41, 1374, 1000, 1383, 1381, 44, 1010, 1324, 1011, 999,
 1383, 1000, 1400, 1391, 1041, 1010, 1324, 1011, 1374, 1042,
 1398, 40, 1010, 1763, 1011, 1779, 41, 1400, 1000, 1412,
 1406, 212, 210, 213, 197, 1412, 198, 193, 204, 211,
 197, 1435, 1417, 193, 206, 196, 1420, 207, 210, 1425,
 201, 205, 208, 204, 1431, 197, 209, 213, 201, 214,
 1435, 197, 209, 214, 1443, 1441, 206, 207, 212, 1471,
 1443, 1471, 1447, 1447, 1435, 1447, 1454, 1452, 1412, 1435,
 999, 1454, 1000, 1471, 1469, 201, 198, 1454, 212, 200,
 197, 206, 1443, 197, 204, 211, 197, 1454, 1471, 1443,
 1486, 1476, 1324, 1967, 1324, 1480, 1001, 1045, 1356, 1482,
 1400, 1486, 40, 1454, 41, 1510, 1495, 201, 206, 212,
 197, 199, 197, 210, 1500, 210, 197, 193, 204, 1508,
 194, 207, 207, 204, 197, 193, 206, 1510, 1000, 1523,
 1521, 59, 1601, 214, 193, 204, 213, 197, 1013, 1012,
 1523, 1000, 1553, 1532, 204, 193, 194, 197, 204, 1026,
 1300, 1541, 211, 215, 201, 212, 195, 200, 1043, 1300,
 1550, 211, 212, 210, 201, 206, 199, 1028, 1300, 1553,
 1486, 1553, 1578, 1562, 193, 210, 210, 193, 217, 1021,
 1300, 1575, 208, 210, 207, 195, 197, 196, 213, 210,
 197, 1022, 1300, 1623, 1578, 1017, 1300, 1586, 1584, 40,
 1001, 1586, 41, 1586, 1000, 1593, 1591, 1593, 1001, 999,
 1593, 1000, 1601, 1596, 44, 1601, 41, 1014, 58, 40,
 1614, 1612, 195, 207, 205, 205, 197, 206, 212, 1005,
 999, 1614, 1000, 1623, 1621, 59, 1601, 1013, 1523, 999,
 1623, 1000, 1644, 1642, 59, 195, 207, 205, 205, 197,
 206, 212, 1010, 40, 1001, 1586, 41, 1649, 1661, 1011,
 1040, 1644, 1000, 1649, 1647, 58, 1649, 1000, 1661, 1659,
 1644, 214, 193, 204, 213, 197, 1013, 1012, 1661, 1000,
 1669, 1667, 1644, 1013, 1669, 1661, 1669, 1000, 1696, 1677,
 204, 193, 194, 197, 204, 1718, 1685, 211, 215, 201,
 212, 195, 200, 1718, 1693, 211, 212, 210, 201, 206,
 199, 1718, 1696, 1486, 1696, 1718, 1704, 193, 210, 210,
 193, 217, 1718, 1715, 208, 210, 207, 195, 197, 196,
 213, 210, 197, 1718, 1718, 1017, 1718, 1722, 1722, 1001,
 1722, 1729, 1727, 44, 1001, 999, 1729, 1000, 1737, 1733,
 1001, 1383, 1737, 40, 1737, 41, 1754, 1752, 201, 198,
 1454, 212, 200, 197, 206, 1729, 197, 204, 211, 197,
 1737, 1754, 1729, 1763, 1761, 44, 1010, 1737, 1011, 999,
 1763, 1000, 1779, 1766, 1008, 1770, 1001, 1356, 1035, 1773,
 1324, 1035, 1776, 1454, 1035, 1779, 1737, 1035, 1788, 1786,
 1593, 1010, 1763, 1011, 999, 1788, 1000, 1803, 1796, 1020,
 1356, 58, 61, 1803, 1454, 1803, 1019, 1356, 58, 61,
 1814, 1324, 1814, 1812, 1025, 1004, 1020, 1356, 58, 61,
 999, 1814, 1000, 1825, 1823, 1025, 1004, 1019, 1356, 58,
 61, 999, 1825, 1000, 1847, 1838, 211, 212, 197, 208,
 1324, 213, 206, 212, 201, 204, 1324, 1845, 215, 200,
 201, 204, 197, 1454, 1847, 1000, 1855, 1853, 44, 1324,
 1825, 999, 1855, 1000, 1864, 1862, 44, 1324, 58, 1324,
 999, 1864, 1000, 1876, 1868, 1017, 1300, 1876, 193, 210,
 210, 193, 217, 1021, 1918, 1881, 1881, 1300, 1887, 1881,
 1887, 1885, 44, 1876, 1887, 1000, 1897, 1890, 1897, 1897,
 1041, 1324, 58, 1324, 1855, 1042, 1907, 1907, 1041, 1038,
 1002, 58, 1038, 1002, 1907, 1042, 1918, 1916, 44, 1038,
 1002, 58, 1038, 1002, 1907, 1918, 1000, 1923, 1923, 1300,
 1897, 1923, 1929, 1927, 44, 1918, 1929, 1000, 1967, 1954,
 208, 210, 207, 195, 197, 196, 213, 210, 197, 1022,
 1033, 1010, 1001, 1018, 1578, 1015, 1510, 1614, 59, 1601,
 1011, 2006, 2111, 1963, 193, 210, 210, 193, 217, 1021,
 1024, 1876, 1967, 1017, 1023, 1300, 2006, 1970, 61, 1973,
 62, 61, 1975, 62, 1978, 60, 62, 1981, 60, 61,
 1983, 60, 1985, 35, 1988, 197, 209, 1991, 199, 197,
 1994, 199, 212, 1997, 206, 197, 2000, 204, 197, 2003,
 204, 212, 2006, 92, 61, 2015, 2013, 1029, 1001, 58,
 1034, 2006, 2015, 1000, 2035, 2018, 2172, 2023, 198, 207,
 210, 2035, 2033, 201, 198, 1454, 212, 200, 197, 206,
 2006, 2088, 2035, 1040, 2050, 2050, 1010, 1004, 1356, 58,
 61, 1324, 1825, 1011, 1847, 196, 207, 2006, 2078, 2070,
 2053, 2172, 2058, 198, 207, 210, 2035, 2068, 201, 198,
 1454, 212, 200, 197, 206, 2006, 2088, 2070, 1000, 2078,
 2076, 1601, 2006, 2015, 1036, 2078, 1015, 2088, 2086, 194,
 197, 199, 201, 206, 1015, 2088, 2050, 2106, 2096, 194,
 197, 199, 201, 206, 2070, 2101, 198, 207, 210, 2035,
 2104, 2172, 2151, 2106, 2151, 2111, 2109, 1001, 2111, 1000,
 2151, 2120, 193, 204, 199, 207, 204, 2106, 1016, 2131,
 197, 216, 212, 197, 210, 206, 193, 204, 2106, 1016,
 2141, 198, 207, 210, 212, 210, 193, 206, 2106, 1016,
 2147, 194, 197, 199, 201, 206, 2151, 1037, 1013, 2050,
 2162, 2160, 197, 204, 211, 197, 1013, 2006, 2162, 2162,
 1000, 2172, 2170, 194, 197, 199, 201, 206, 2070, 2172,
 2050, 2186, 2177, 1025, 1004, 1788, 2180, 1001, 1356, 2186,
 199, 207, 212, 207, 1737, 2280, 2190, 2015, 1006, 2198,
 197, 206, 196, 1016, 1007, 2151, 1006, 2207, 195, 207,
 205, 205, 197, 206, 212, 1005, 2211, 1486, 1929, 1006,
 2219, 194, 197, 199, 201, 206, 2070, 1006, 2237, 211,
 215, 201, 212, 195, 200, 1027, 1001, 1018, 1031, 58,
 61, 1010, 1737, 1011, 1754, 1006, 2245, 207, 215, 206,
 1032, 1486, 1864, 1006, 2251, 1029, 1001, 58, 1034, 2186,
 2253, 59, 2261, 195, 207, 196, 197, 207, 206, 1006,
 2270, 195, 207, 196, 197, 207, 198, 198, 1006, 2280,
 208, 210, 207, 199, 210, 193, 205, 1001, 1006;
CONSTINTEGER SS= 2186
CONSTINTEGER LAST SNAME=66; ! NO OF THE LAST SPECIAL NAME
OWNINTEGERARRAY SNNNO(0:LAST SNAME+1)
CONSTBYTEINTEGERARRAY TSNAME(0:LAST SNAME)=2,1(3),0,2(8),1,2,0(10),1,2,
 0(6),1,0,0,2,0(3),1,
 2,0,0,3,0(3),1,1,0(17);
CONSTINTEGERARRAY BYTES(0:4)=0,4,8,4,8
CONSTINTEGERARRAY SIZECODE(0:5)=0,5,6,5,5,3;
OWNINTEGERARRAY FIXED GLA(0:13)=0,
 0(3),-1,0,0(6),X'30000000',0;
CONSTBYTEINTEGERARRAY TRTAB(0:255)=0(48),
 1(10),0(7),2(26),0(6),2(26),0(5),0(128)
CONSTINTEGERARRAY GRMAP(0:4)=0,1,3,5,7;
CONSTBYTEINTEGERARRAY ITOETAB(0 : 255) = C 
 X'00',X'01',X'02',X'03', X'37',X'2D',X'2E',X'2F',
 X'16',X'05',X'25',X'0B', X'0C',X'0D',X'0E',X'0F',
 X'10',X'11',X'12',X'13', X'3C',X'3D',X'32',X'26',
 X'18',X'19',X'3F',X'27', X'1C',X'1D',X'1E',X'1F',
 X'40',X'4F',X'7F',X'7B', X'5B',X'6C',X'50',X'7D',
 X'4D',X'5D',X'5C',X'4E', X'6B',X'60',X'4B',X'61',
 X'F0',X'F1',X'F2',X'F3', X'F4',X'F5',X'F6',X'F7',
 X'F8',X'F9',X'7A',X'5E', X'4C',X'7E',X'6E',X'6F',
 X'7C',X'C1',X'C2',X'C3', X'C4',X'C5',X'C6',X'C7',
 X'C8',X'C9',X'D1',X'D2', X'D3',X'D4',X'D5',X'D6',
 X'D7',X'D8',X'D9',X'E2', X'E3',X'E4',X'E5',X'E6',
 X'E7',X'E8',X'E9',X'4A', X'E0',X'5A',X'5F',X'6D',
 X'79',X'81',X'82',X'83', X'84',X'85',X'86',X'87',
 X'88',X'89',X'91',X'92', X'93',X'94',X'95',X'96',
 X'97',X'98',X'99',X'A2', X'A3',X'A4',X'A5',X'A6',
 X'A7',X'A8',X'A9',X'C0', X'6A',X'D0',X'A1',X'07',
 X'20',X'21',X'22',X'23', X'24',X'15',X'06',X'17',
 X'28',X'29',X'2A',X'2B', X'2C',X'09',X'0A',X'1B',
 X'30',X'31',X'1A',X'33', X'34',X'35',X'36',X'08',
 X'38',X'39',X'3A',X'3B', X'04',X'14',X'3E',X'E1',
 X'41',X'42',X'43',X'44', X'45',X'46',X'47',X'48',
 X'49',X'51',X'52',X'53', X'54',X'55',X'56',X'57',
 X'58',X'59',X'62',X'63', X'64',X'65',X'66',X'67',
 X'68',X'69',X'70',X'71', X'72',X'73',X'74',X'75',
 X'76',X'77',X'78',X'80', X'8A',X'8B',X'8C',X'8D',
 X'8E',X'8F',X'90',X'9A', X'9B',X'9C',X'9D',X'9E',
 X'9F',X'A0',X'AA',X'AB', X'AC',X'AD',X'AE',X'AF',
 X'B0',X'B1',X'B2',X'B3', X'B4',X'B5',X'B6',X'B7',
 X'B8',X'B9',X'BA',X'BB', X'BC',X'BD',X'BE',X'BF',
 X'CA',X'CB',X'CC',X'CD', X'CE',X'CF',X'DA',X'DB',
 X'DC',X'DD',X'DE',X'DF', X'EA',X'EB',X'EC',X'ED',
 X'EE',X'EF',X'FA',X'FB', X'FC',X'FD',X'FE',X'FF'
CONSTINTEGER MAXLEVELS=31
CONSTINTEGER UNASSPAT=X'81818181'
CONSTINTEGER JOBBERBIT=X'40000000'; ! BIT FOR JOBBER MODE
CONSTINTEGER CEBIT=1; ! BIT FOR RUNNING UNDER COMPILER ENVIRONMENT
CONSTINTEGER MAXDICT=X'100'; ! BIT FOR MAXIMUM DICTIONARY
!
! THE PRINCIPAL OPCODES ARE HERE DEFINED AS THEIR MNEMONICS(AMENDED)
!
CONSTINTEGER LB=X'7A',SLB=X'52',STB=X'5A',ADB=X'20',CPB=X'26', C 
 MYB=X'2A',SBB=X'22',CPIB=X'2E'
CONSTINTEGER LD=X'78',LDA=X'72',INCA=X'14',STD=X'58',LDB=X'76', C 
 LDTB=X'74',LDRL=X'70',CYD=X'12',MODD=X'16'
CONSTINTEGER STLN=X'5C',ASF=X'6E',ST=X'48',RALN=X'6C',LXN=X'7E',C 
 LLN=X'7C',LSS=X'62',SLSS=X'42',MPSR=X'32',STSF=X'5E',C 
 LUH=X'6A',STUH=X'4A',LSD=X'64',SLSD=X'44',PRCL=X'18', C 
 LSQ=X'66',SLSQ=X'46',STXN=X'4C',LCT=X'30',STCT=X'36'
CONSTINTEGER JUNC=X'1A',JLK=X'1C',CALL=X'1E',EXIT=X'38',JCC=2, C 
 JAT=4,JAF=6,DEBJ=X'24',CPSR=X'34',ESEX=X'3A'
CONSTINTEGER IAD=X'E0',ICP=X'E6',USH=X'C8',ISB=X'E2',IRSB=X'E4',C 
 OR=X'8C',UCP=X'C6',IMY=X'EA',IMDV=X'AE',AND=X'8A', C 
 ISH=X'E8',NEQ=X'8E'
CONSTINTEGER RAD=X'F0',RSB=X'F2',RRSB=X'F4',FLT=X'A8',RRDV=X'BC', C 
 RSC=X'F8',FIX=X'B8',RMY=X'FA',RCP=X'F6'
!
CONSTINTEGER MVL=X'B0',MV=X'B2'
CONSTBYTEINTEGERARRAY OCODE(-1:47)=X'1E',X'1C',2(14),X'1A',4(16),6(16);
 ! JLK=1C,J=1A,JCC=2,JAT=4,JAF=6
!
! DEFINE SOME MNEMONICS FOR THE VISIBLE REGISTERS
!
CONSTINTEGER ACCR=0,DR=1,LNB=2,XNB=3,PC=4,CTB=5,TOS=6,BREG=7
CONSTBYTEINTEGERARRAY LDCODE(0:7)=0,X'78',X'7C',X'7E',0,48,0,X'7A';
!
CONSTSTRING (4)DEFAULTMAINEP='S#GO'
CONSTSTRING (8)MDEP='S#NDIAG'
CONSTSTRING (8)SIGEP='S#SIGNAL'; ! EP FOR SIGNAL
CONSTSTRING (11)AUXSTEP='ICL9CEAUXST';! EP FOR AUX STACK
CONSTINTEGER LABBYNAME=1; ! BIT SET IN PASS2INF FOR LABS
CONSTINTEGER SWBYNAME=2; ! DITTO FOR SWITCHES AS PARAMS
!
CONSTINTEGER SNPT=X'1006'; ! SPECIALNAME PTYPE
INTEGER RPPTR, KYCHAR1, KYCHAR2, LEVELINF, RPBASE, ASLMAX, C 
 AUXST,CDCOUNT, FREE FORMAT, PASS2INF, P1SIZE, DICTBASE
INTEGER ASL, NNAMES, ARSIZE, CABUF, PPCURR, CREFHEAD, C 
 CONSTHOLE, CONSTPTR, CONSTBTM, CONSTLIMIT, ASL CUR BTM, C 
 LENGTH, NEXTP, N0, SNUM, RLEVEL, NMAX, USTPTR, PLABEL,C 
 LEVEL, CA, RR, TYPE, LASTNAME, STLIMIT, EBCDIC
INTEGER FAULTY, HIT, INHCODE, TTOPUT, LIST, ADFLAG, C 
 PARMLINE, PARMTRCE, PARMDIAG, PARMOPT, CTYPE, DCOMP, C 
 CPRMODE, PARMCHK, PARMARR, QFLAG, SMAP, PARMDYNAMIC
LONGREAL CVALUE, IMAX
INTEGER MASK, NEXT, N, ITEM, LOGEPDISP, EXPEPDISP, CODEPDISP,C 
 P, Q, R, STRLINK, LINE, S, T, U, V, NEST, FNAME, GLACA, C 
 GLACABUF, GLACURR, SSTL, QMAX, LASTLINE, LASTAT, SLINES, C 
 FILE ADDR, FILE PTR, FILE END, FILE SIZE, LASTEND, C 
 PARMBITS1, PARMBITS2, WKFILEAD, WKFILESEGS, GLARELOCS
SYSTEMINTEGERMAPSPEC COMREG(INTEGER N)
RECORDFORMAT LISTF(INTEGER S1,S2,S3,LINK)
BEGIN 
 FILE ADDR=COMREG(46); ! SOURCE FILE IF CLEAN
 PARMBITS1=COMREG(27)
 PARMBITS2=COMREG(28)
 WKFILEAD=COMREG(14)
 WKFILESEGS=INTEGER(WKFILEAD+8)>>18
 IF FILE ADDR=0 THEN START 
 FILE SIZE=32000*(FILE ADDR+2)
 FINISH ELSE START 
 FILE PTR=FILE ADDR+INTEGER(FILE ADDR+4)
 FILE END=FILE ADDR+INTEGER(FILE ADDR)
 FILE SIZE=INTEGER(FILE ADDR)
 FINISH 
 ARSIZE=WKFILESEGS<<16
 NNAMES=511
 IF PARMBITS1&JOBBERBIT=0 THEN START 
 IF FILESIZE>32000 THEN NNAMES=1023
 IF PARMBITS2&MAXDICT#0 OR WKFILESEGS>2 THEN NNAMES=2047
 FINISH 
 IF PARMBITS2&CEBIT=0 OR PARMBITS1&JOBBERBIT#0 START 
 ! EMAS&JOBBER MODES PRINT HEADER
 NEWLINES(3); SPACES(5)
 PRINTSTRING( 'EDINBURGH ALGOL 60M COMPILER ')
 PRINTSTRING( ' VERSION 60')
 NEWLINES(3)
 FINISH 
 ASL=3*NNAMES
 IF ASL>4095 THEN ASL=4095
 ASLMAX=ASL
END 
RECORDARRAY ASLIST(0:ASL)(LISTF)
INTEGERARRAY SET, STACKBASE, RAL, FLAG, L, M, NMDECS, C 
 JROUND, NAMES(0:MAXLEVELS)
BYTEINTEGERARRAYFORMAT CCF(0:FILESIZE+7)
BYTEINTEGERARRAYNAME CC
INTEGERARRAYFORMAT AF(0:ARSIZE)
INTEGERARRAYNAME A,CCLINES
INTEGERARRAY WRD, TAGS(0:NNAMES)
SYSTEMROUTINESPEC LPUT(INTEGER A, B, C, D)
ROUTINESPEC WARN(INTEGER N,V)
ROUTINESPEC FAULT(INTEGER N, VALUE)
ROUTINESPEC PRINT NAME(INTEGER N)
ROUTINESPEC CLEARLIST(INTEGERNAME HEAD)
ROUTINESPEC BINSERT(INTEGERNAME T,B,INTEGER S1,S2,S3)
ROUTINESPEC FROM123(INTEGER CELL, INTEGERNAME S1, S2, S3)
ROUTINESPEC POP(INTEGERNAME C, INTEGERNAME P, Q, R)
INTEGERFNSPEC MORE SPACE
ROUTINESPEC PUSH(INTEGERNAME C, INTEGER S1, S2, S3)
INTEGERFNSPEC FIND(INTEGER LAB, LIST)
!%INTEGERFNSPEC FIND3(%INTEGER LAB, LIST)
ROUTINESPEC MLINK(INTEGERNAME CELL)
STRING (31)MAINEP
ROUTINESPEC PRHEX(INTEGER VALUE,PLACES)
IF VMEB=YES THEN START 
 SYSTEMROUTINESPEC FAULTMK(INTEGER ONOFF)
FINISH 
IF ALLOW CODELIST=YES THEN START 
 SYSTEMROUTINESPEC NCODE(INTEGER A,B,C)
FINISH 
 ! START OF COMPILATION
 CC==ARRAY(WKFILEAD+INTEGER(WKFILEAD+8)>>1, CCF)
 CCLINES==ARRAY(WKFILEAD+INTEGER(WKFILEAD+4), AF)
 A==ARRAY(ADDR(CC(0))+4096, AF)
BEGIN 
ROUTINESPEC COMPARE
ROUTINESPEC PNAME(INTEGER MODE)
INTEGERFNSPEC CONST(INTEGER MODE)
ROUTINESPEC TEXTTEXT
ROUTINESPEC READ PRG
CONSTBYTEINTEGERARRAY ILETT(0:533)=3,
 'A','B','S',
 4,'I','A','B','S',
 4,'S','I','G','N',
 6,'E','N','T','I','E','R',
 11,'C','L','O','S','E','S','T','R','E','A','M',
 4,'S','Q','R','T',
 3,'S','I','N',
 3,'C','O','S',
 6,'A','R','C','T','A','N',
 2,'L','N',
 3,'E','X','P',
 7,'M','A','X','R','E','A','L',
 7,'M','I','N','R','E','A','L',
 6,'M','A','X','I','N','T',
 7,'E','P','S','I','L','O','N',
 5,'F','A','U','L','T',
 4,'S','T','O','P',
 8,'I','N','S','Y','M','B','O','L',
 9,'O','U','T','S','Y','M','B','O','L',
 6,'I','N','R','E','A','L',
 7,'O','U','T','R','E','A','L',
 9,'I','N','I','N','T','E','G','E','R',
 13,'O','U','T','T','E','R','M','I','N','A','T','O','R',
 10,'O','U','T','I','N','T','E','G','E','R',
 9,'O','U','T','S','T','R','I','N','G',
 6,'L','E','N','G','T','H',
 7,'C','P','U','T','I','M','E',
 11,'S','E','L','E','C','T','I','N','P','U','T',
 12,'S','E','L','E','C','T','O','U','T','P','U','T',
 7,'N','E','W','L','I','N','E',
 5,'S','P','A','C','E',
 8,'N','E','W','L','I','N','E','S',
 6,'S','P','A','C','E','S',
 10,'N','E','X','T','S','Y','M','B','O','L',
 11,'P','R','I','N','T','S','Y','M','B','O','L',
 10,'R','E','A','D','S','Y','M','B','O','L',
 4,'R','E','A','D',
 7,'N','E','W','P','A','G','E',
 5,'P','R','I','N','T',
 11,'P','R','I','N','T','S','T','R','I','N','G',
 4,'C','O','D','E',
 8,'R','E','A','D','1','9','0','0',
 9,'P','R','I','N','T','1','9','0','0',
 6,'O','U','T','P','U','T',
 11,'R','E','A','D','B','O','O','L','E','A','N',
 12,'W','R','I','T','E','B','O','O','L','E','A','N',
 9,'W','R','I','T','E','T','E','X','T',
 8,'C','O','P','Y','T','E','X','T',
 6,'R','E','A','D','C','H',
 6,'N','E','X','T','C','H',
 7,'P','R','I','N','T','C','H',
 6,'S','K','I','P','C','H',
 7,'M','O','N','I','T','O','R',
 6,'O','P','E','N','D','A',
 6,'O','P','E','N','S','Q',
 7,'C','L','O','S','E','D','A',
 7,'C','L','O','S','E','S','Q',
 5,'P','U','T','D','A',
 5,'G','E','T','D','A',
 5,'P','U','T','S','Q',
 5,'G','E','T','S','Q',
 6,'R','W','N','D','S','Q',
 6,'I','N','C','H','A','R',
 7,'O','U','T','C','H','A','R',
 10,'P','A','P','E','R','T','H','R','O','W',
 8,'P','U','T','A','R','R','A','Y',
 8,'G','E','T','A','R','R','A','Y',
 255
CONSTBYTEINTEGERARRAY ITYPE(0:LAST SNAME+1)=0,130,
 129(3),128,130(8),129,130,128(10),129,130,
 128(6),129,128(2),130,128(3),129,
 130,128(2),131,128(3),129(2),128(17);
INTEGER I, J, LL, DSIZE, SAVQ, ANALFAIL
 DSIZE=8*NNAMES
INTEGERARRAY NTYPE,DPOSN(0:NNAMES)
BYTEINTEGERARRAY LETT(0:DSIZE+20)
 CABUF=0; PPCURR=0; PASS2INF=0
 LINE=1; RLEVEL=0; NMAX=0; USTPTR=0
 LEVEL=0; CA=0; LASTAT=0
 FAULTY=0; ADFLAG=0; STRLINK=0
 DCOMP=0; CPRMODE=0
 CONSTHOLE=0; CREFHEAD=0
 NEXT=1
 DICTBASE=ADDR(LETT(0))
 LOGEPDISP=0; EXPEPDISP=0; CODEPDISP=0
 IMAX=(-1)>>1; PLABEL=24999
 SSTL=0; LASTLINE=1; SNUM=0; CDCOUNT=0; RPPTR=0
 LETT(0)=0
 N0=14; N=12
 GLACA=N0<<2; GLACABUF=GLACA; GLARELOCS=0
 GLACURR=0; PARMOPT=1; PARMARR=1
 PARMLINE=1; PARMTRCE=1; PARMDIAG=1; INHCODE=0
 LIST=1; PARMCHK=1
 LEVELINF=0
 I=PARMBITS1
 EBCDIC=PARMBITS1>>22&1
 STLIMIT=X'1F000'
 IF I>>24&1#0 THEN STLIMIT=COMREG(48)
 FREE FORMAT=I&X'80000'; ! FREE = NO SEQUENCE NOS
 QFLAG=I&1
 LIST=0 IF I&2#0
 PARMLINE=0 IF I&X'800000'#0
 PARMDIAG=0 IF I&4#0
 PARMCHK=0 IF I&16#0
 PARMARR=0 IF I&32#0
 PARMDYNAMIC=I>>20&1; ! REFS ONTO DYNAMIC LISTHEAD
 IF ALLOW CODELIST=YES THEN DCOMP=I>>14&1;! PARM 'CODE' BIT
 TTOPUT=COMREG(40)
 SMAP=I>>7&1
 PARMTRCE=0 AND PARMDIAG=0 IF I&64#0
 IF I&(1<<16)#0 THEN START 
 PARMARR=0; PARMOPT=0
 PARMLINE=0; PARMCHK=0; PARMDIAG=0
 FINISH 
 MAINEP=DEFAULT MAINEP
 IF QFLAG=0 THEN KYCHAR1='%' AND KYCHAR2=' ' C 
 ELSE KYCHAR1='''' AND KYCHAR2=''''
 CYCLE I=0, 1, MAXLEVELS
 SET(I)=0; STACKBASE(I)=0; RAL(I)=0
 FLAG(I)=0
 L(I)=0; M(I)=0
 JROUND(I)=0
 NAMES(I)=-1
 REPEAT 
 IF INCLUDE HANDCODE=NO START 
 CYCLE I=0, 1, NNAMES
 WRD(I)=0
 TAGS(I)=0
 NTYPE(I)=0
 REPEAT 
 FINISH ELSE START 
 *LB_NNAMES
 *ADB_1
 *MYB_4
 *ADB_X'18000000'
 *LDA_WRD+4
 *LDTB_B 
 *MVL_L =DR ,0,0
 *LDA_TAGS+4
 *LDTB_B 
 *MVL_L =DR ,0,0
 *LDA_NTYPE+4
 *LDTB_B 
 *MVL_L =DR ,0,0
 FINISH 
 ASL CUR BTM=ASL-240
 CONST LIMIT=4*ASL CUR BTM-8
 CYCLE I=ASL CUR BTM,1,ASL-1
 ASLIST(I+1)_LINK=I
 REPEAT 
 ASLIST(ASL CUR BTM)_LINK=0
 ASLIST(0)_S1=-1
 ASLIST(0)_S2=-1
 ASLIST(0)_S3=-1
 ASLIST(0)_LINK=0
 K=0; LL=1; I=ILETT(0)
 WHILE I<255 CYCLE 
 CYCLE J=1, 1, I
 CC(J)=ILETT(J+K); ! COPY SPECIAL NAMES TO SOURCE
 REPEAT ; CC(J+1)=';'
 R=2; Q=1; PNAME(1); ! SPECIAL NAME TO DICTIONARY
 NTYPE(LASTNAME)<-ITYPE(LL)<<8
 DPOSN(LASTNAME)=-1
 SNNNO(LL)=LASTNAME
 LL=LL+1
 K=K+I+1
 I=ILETT(K)
 REPEAT ; ! AND COMPILED
 SNUM=LL-1
 LASTAT=-2
 LPUT(0, 1, 1, ADDR(LETT(1)))
 READPRG
 LENGTH=LENGTH+5
 CC(LENGTH)=';'
 CC(LENGTH+1)='C'+128
 CC(LENGTH+2)='E'+128
 CC(LENGTH+3)='N'+128
 CC(LENGTH+4)='D'+128
 CC(LENGTH+5)=';'
 LENGTH=LENGTH+5
!
! MOVE CC DOWN ON TOP OF LINEARRAY AND THEN MAP A ONTO FREE WORKFILE
!
 LASTLINE=LINE
 I=(ADDR(CCLINES(LASTLINE+1))+15)&(-16)
 J=ADDR(CC(0))
 IF I>J THEN FAULT(102,0)
 IF INCLUDE HANDCODE=NO THEN START 
 CYCLE K=0,1,LENGTH
 BYTEINTEGER(I+K)=CC(K)
 REPEAT 
 FINISH ELSE START 
 *LDTB_X'18000000'; *LDB_LENGTH
 *LDA_J; *CYD_0
 *LDA_I
 *MV_L =DR 
 FINISH 
 CC==ARRAY(I,CCF)
 NEWLINES(2)
 I=(ADDR(CC(LENGTH))+4095)>>12<<12
 J=ADDR(CCLINES(0))+16*4096*WKFILESEGS
 IF J>I THEN I=J
 A==ARRAY(I, AF)
 ARSIZE=(WKFILEAD+WKFILESEGS<<18-I)>>2-512
 SLINES=LINE
 Q=1; QMAX=1; LINE=1
 CYCLE R=0,1,7
 A(R)=0
 REPEAT 
 STACKBASE(1)=5; ! TO LINK GLOBAL PROCS
 R=8; LEVEL=1
 UNTIL Q>=LENGTH-6 CYCLE 
 SAVQ=Q; ! VERY EFFICIENT COMPARE DOES
 QMAX=Q; ! MINIMUM RESTTING Q MAY BE WRONG
 P=SS
 WHILE CCLINES(LINE+1)<=Q THEN LINE=LINE+1
 RR=R; A(R+1)=LINE
 R=R+2
 ANALFAIL=0
 COMPARE
 FAULT(102, 0) IF R>ARSIZE
 IF HIT=0 THEN START 
 Q=SAVQ; ! ENSURE FAULT MSG IS RIGHT
 FAULT(100,ANALFAIL)
 R=RR
 FINISH ELSE START 
 A(RR)=R-RR
 IF LEVEL=0 THEN FAULT(14, 0) AND EXIT 
 FINISH 
 REPEAT 
 !DEAL WITH END OF PROGRAM
 FAULT(15,0) IF LEVEL>1 OR JROUND(1)&255#0;! MISSING ENDS
 A(R)=0; R=R+1
 A(R)=0; R=R+1
 P1SIZE=R
 DICTBASE=ADDR(A(R))
 R=R+(NEXT+7)>>2
 RPPTR=(R+256)&(-256)
 RPBASE=RPPTR
 FAULT(102,0) IF RPBASE>ARSIZE
 IF INCLUDE HANDCODE=NO THEN START 
 CYCLE I=0,1,NEXT
 BYTEINTEGER(DICTBASE+I)=LETT(I)
 REPEAT 
 FINISH ELSE START 
 *LDTB_X'18000000'
 *LDB_NEXT
 *LDA_LETT+4
 *CYD_0
 *LDA_DICTBASE
 *MV_L =DR 
 FINISH 
 ->BEND
!
! THE ARRAY KEYCHK IS TO ALLOW ECMA KEYWORDS TO BE CHECKED. SINCE PASS 2
! DOES A FULL CHECK THIS APPEARS UNNECESSARY BUT IT HELPS TO STOP THE
! LEXICAL SCANNER GETIING INTO TROUBLE WHEN SPARE SINGLE QUOTES ARE
! SCATTERED ABOUT THE SOURCE TEXT.
! FOR EACH INITIAL LETTER THERE IS A BITMASK. THE TOP 24 BITS INDICATE
! VALID SECOND LETTERS X'80000000'=A ETC AND THE BOTTOM 8 BIT INDICATE
! VALID KEYWORD LENGTHS 1=2LETTERS X'80'=9LETTERS ETC
! THE ARRAY IS BASE ON THE FOLLOWING ALGOL KEYWORDS:-
!
! AND,ALGOL,ARRAY,BOOLEAN,BEGIN,COMMENT,CODEON,CODEOFF,DO,DIV
! EQUIV,ELSE,EQ,END,EXTERNAL,FOR,FORTRAN,FALSE,GT,GE,GOTO,GO
! IF,IMPL,INTEGER,LABEL,LT,LE,NOT,NE,OR,OWN
! PROCEDURE,PROGRAM,POWER,REAL,SWITCH,STRING,STEP
! THEN,TRUE,TO,UNTIL,VALUE,WHILE
!
CONSTINTEGERARRAY KEYCHK('A':'Z')=C 
 X'0014400A',X'08020028',X'00020030',X'00820003',
 X'0014814F',X'8002002A',X'08021005',0,
 X'040C0025',0,0,X'88001009',
 0,X'08020003',X'00004203',X'000240A8',
 0,X'08000004',X'00001214',X'01024005',
 X'00040008',X'80000008',X'01000008',0,
 0(2);
CONSTBYTEINTEGERARRAY ULINED(0:127)= C 
 X'00',X'01',X'02',X'03',X'04',X'05',X'06',X'07',
 X'08',X'09',X'0A',X'0B',X'0C',X'0D',X'0C',X'0F',
 X'10',X'11',X'12',X'13',X'14',X'15',X'16',X'17',
 X'18',X'19',X'1A',X'1B',X'1C',X'1D',X'1C',X'1F',
 X'20',X'21',X'22',X'23',X'24',X'25',X'26',X'27',
 X'28',X'29',X'2A',X'2B',X'2C',X'2D',X'2C',X'2F',
 X'30',X'31',X'32',X'33',X'34',X'35',X'36',X'37',
 X'38',X'39',X'3A',X'3B',X'3C',X'3D',X'3C',X'3F',
 X'40',X'C1',X'C2',X'C3',X'C4',X'C5',X'C6',X'C7',
 X'C8',X'C9',X'CA',X'CB',X'CC',X'CD',X'CE',X'CF',
 X'D0',X'D1',X'D2',X'D3',X'D4',X'D5',X'D6',X'D7',
 X'D8',X'D9',X'DA',X'5B',X'5C',X'5D',X'5E',X'5F',
 X'60',X'C1',X'C2',X'C3',X'C4',X'C5',X'C6',X'C7',
 X'C8',X'C9',X'CA',X'CB',X'CC',X'CD',X'CE',X'CF',
 X'D0',X'D1',X'D2',X'D3',X'D4',X'D5',X'D6',X'D7',
 X'D8',X'D9',X'DA',X'7B',X'7C',X'7D',X'7E',X'7F';
ROUTINE READ PRG
ROUTINESPEC GET LINE
INTEGER DEL
BYTEINTEGERARRAY BLINE(-20:161),TLINE(0:161)
CONSTINTEGER NBASICS=8
CONSTINTEGER MAXSIZE=11
CONSTINTEGERARRAY BASSYM(0:9)='<','[','>',']','(',123,
 ')',125,'-','_';
INTEGERARRAY WORD(0:MAXSIZE+1)
INTEGER SIZE,LETTERFLAG,LL,LP,I,J,BLD0,BLD1
 LL=0; LP=0
 LENGTH=-4; DEL=0
 IF LIST#0 THEN PRINTSTRING(" LINE
")
 CYCLE K=-20,1,0
 BLINE(K)=' '
 REPEAT 
 BLD0=X'180000A1'
 BLD1=ADDR(BLINE(1)); ! BLD IS DECRPTR TO BLINE
L2: LP=LP+1
 IF LP>LL THEN START 
 GET LINE
 LP=1
 IF BLINE(1)=25 THEN RETURN 
 FINISH 
 I=TLINE(LP)
 IF 10#I<=31 OR I>126 THEN ->L2
 IF I='''' AND QFLAG#0 START 
!
! QLAG=1 IFF PARM(BCD),IE USING 1900 OR D.I.N. REPRESENTATIONS
!
 LETTERFLAG=1
 SIZE=0
 CYCLE 
 LP=LP+1
 IF LP>LL THEN GET LINE AND LP=1
 I=TLINE(LP)
 EXIT IF I='''' ;! ***END OF QUOTED WORD
 IF 33<=I<=126 START 
 SIZE=SIZE+1 ;! ***LENGTH OF QUOTED WORD
 WORD(SIZE)=I
 IF TRTAB(I)#2 THEN LETTERFLAG=0
!
! ***NOT ALL LETTERS-CANNOT BE KEYWORD
!
 CC(LENGTH+SIZE+4)=ULINED(I)
 EXIT IF SIZE>MAXSIZE
 FINISH ELSE START 
 IF I=10 THEN LINE=LINE+1 AND C 
 CCLINES(LINE)=LENGTH+SIZE+6
 IF I=25 THEN ->CODS
 FINISH 
 REPEAT 
!
! HAVE A KEYWORD OF SORTS IN WORD AND THE UNDERLINED VERSION OF SAME
! ALREADY PLACED IN CC
!
! CHECK FIRST FOR VALID UNDERLINED WORD
!
 IF LETTERFLAG=1 AND 0<SIZE<MAXSIZE START 
 I=KEYCHK(WORD(1)&X'5F')
 IF I&X'80000000'>>((WORD(2)-1)&31)=0 OR C 
 I&1<<(SIZE-2)=0 THEN ->CODS
 LENGTH=LENGTH+SIZE
 I=CC(LENGTH+4)
 ->L2
 FINISH 
!
! NEXT CHECK FOR NON ALPHABETIC BASIC SYMBOL USING TABLE BASSYM
!
 IF SIZE=1 THEN START 
 I=WORD(1); ! THE ONLY SYMBOL
 IF I='/' THEN START 
 CC(LENGTH+5)='D'+128
 CC(LENGTH+6)='I'+128
 CC(LENGTH+7)='V'+128
 LENGTH=LENGTH+3; ->L2
 FINISH 
 CYCLE J=0,2,NBASICS
 IF I=BASSYM(J) THEN START 
 CC(LENGTH+5)=BASSYM(J+1)
 LENGTH=LENGTH+1; ->L2
 FINISH 
 REPEAT 
 FINISH 
!
 IF SIZE=2 START 
 IF WORD(1)='1' AND WORD(2)='0' START 
 LENGTH=LENGTH+1
 CC(LENGTH+4)='&'
 ->L2
 FINISH 
 IF WORD(1)='*'=WORD(2) START 
 LENGTH=LENGTH+2
 CC(LENGTH+3)='*'
 CC(LENGTH+4)='*'
 ->L2
 FINISH 
 FINISH 
!
! KEYWORD IS A LOAD OF CODSWALLOP. STUFF IT INTO CC AND ALLOW 
! NEXT PASS TO REPORT IT (NB IT MAY BE IN A STRING OR COMMENT)
! TREAT THE LAST QUOTE AS FIRST QUOTE AGAIN IN CASE OF A MISSING QUOTE
!
CODS: LENGTH=LENGTH+1
 CC(LENGTH+4)=''''
 IF SIZE>0 START 
 CYCLE I=1,1,SIZE
 LENGTH=LENGTH+1
 J=WORD(I); CC(LENGTH+4)=J
 REPEAT 
 FINISH 
 IF TLINE(LP)=M'''' THEN LP=LP-1; ->L2
!
 FINISH 
 IF QFLAG=0 START 
 IF I='%' THEN DEL=128 AND ->L2
 DEL=0 UNLESS TRTAB(I)=2
 IF DEL#0 THEN I=ULINED(I)
 FINISH 
 ->L2 IF I=' '
 IF I=NL THEN START 
 LINE=LINE+1
 CCLINES(LINE)=LENGTH+5
 ->L2
 FINISH 
 LENGTH=LENGTH+1; CC(LENGTH+4)=I
 ->L2
ROUTINE GET LINE
SYSTEMROUTINESPEC IOCP(INTEGER EP,N)
SYSTEMROUTINESPEC SIM2(INTEGER EP,R1,R2,INTEGERNAME R3)
INTEGER K,PU,ST,LS
CONSTBYTEINTEGERARRAY ITOI(0:255)=C 
 32(10),10,32(14),25,26,32(5),
 32,33,34,35,36,37,38,39,40,41,42,43,44,45,46,47,
 48,49,50,51,52,53,54,55,56,57,58,59,60,61,62,63,
 64,65,66,67,68,69,70,71,72,73,74,75,76,77,78,79,
 80,81,82,83,84,85,86,87,88,89,90,91,92,93,94,95,
 96,97,98,99,100,101,102,103,104,105,106,107,108,109,
 110,111,112,113,114,115,116,117,118,119,
 120,121,122,123,124,125,126,32,
 26(5),10,26(10),
 26(16),
 26(14),92,38,
 26(11),35,26(4),
 26(16),
 26(9),35,26(5),94,
 26(32);
 LL=0
 IF FILE ADDR=0 THEN START ; ! SOURCE NOT A 'CLEAN' FILE
 SIM2(0,ADDR(BLINE(1)),0,K)
 LL=K
 IF INCLUDE HANDCODE=NO THEN START 
 CYCLE K=1,1,LL
 BLINE(K)=ITOI(BLINE(K))
 REPEAT 
 FINISH ELSE START 
 *LD_BLD0
 *LDB_LL
 *LSS_ITOI+4
 *LUH_X'18000100'
 *TTR_L =DR 
 FINISH 
 IF BLINE(1)=25 THEN START 
 TLINE(1)=25; TLINE(2)=10
 RETURN 
 FINISH 
 FINISH ELSE START ; ! SOURCE IN EMAS FILE
 IF FILEPTR>=FILE END THEN START 
 BLINE(1)=25; TLINE(1)=25
 TLINE(2)=10; LL=2
 RETURN 
 FINISH 
 IF INCLUDE HANDCODE=YES THEN START 
 *LDA_FILEPTR
 *LB_FILEEND
 *SBB_FILEPTR
 *ADB_X'18000000'
 *LDTB_B 
 *SWNE_L =DR ,0,10
 *JCC_8,<IMP>
 *CYD_0
 *STUH_B 
 *IAD_1
 *ST_B 
 *ISB_FILEPTR
 *ST_LL
 *LDA_FILEPTR
 *STB_FILEPTR
 *LDB_LL
 *CYD_0
 *LDA_BLD1
 *STD_TOS 
 *MV_L =DR ,0,0
 *LD_TOS 
 *LSS_ITOI+4
 *LUH_X'18000100'
 *TTR_L =DR 
 ->OLIST
 FINISH 
IMP:
 UNTIL K=NL OR K=0 CYCLE 
 K=BYTE INTEGER(FILEPTR); ! NEXT CHAR FROM SORCE FILE
 FILE PTR=FILE PTR+1
 BLINE(LL+1)=ITOI(K)
 LL=LL+1
 REPEAT 
OLIST:
 FINISH 
 IF LIST#0 THEN START 
 IF INCLUDE HANDCODE=NO THEN START 
 WRITE(LINE, 5)
 BLINE(-5)=LL+4; ! SPACES(5)
 IOCP(15,ADDR(BLINE(-5)))
 FINISH ELSE START 
 *LSS_LINE
 *CDEC_0
 *DSH_9
 *LDTB_X'18000006'
 *LDA_BLD1
 *INCA_-11
 *CPB_B 
 *SUPK_L =6,0,32
 *INCA_-6
 *LDB_6
 *ANDS_L =6,0,63
 BLINE(-11)=LL+10
 IOCP(15,ADDR(BLINE(-11)))
 FINISH 
 NEWLINE
 FINISH 
 IF FREE FORMAT=0 AND LL>73 THEN BLINE(73)=10 AND LL=73
 PU=1; ST=1; LS=0
 IF INCLUDE HANDCODE=NO THEN START 
 IF QFLAG=1 START 
 UNTIL K=10 CYCLE 
 K=BLINE(PU)
 PU=PU+1
 IF K#' 'THEN TLINE(ST)=K AND ST=ST+1
 REPEAT 
 FINISH ELSE START 
 UNTIL K=10 CYCLE 
 K=BLINE(PU)
 PU=PU+1
 UNLESS K=' ' AND (LS<'A' OR LS>'Z') THEN C 
 TLINE(ST)=K AND ST=ST+1 AND LS=K
 REPEAT 
 FINISH 
 LL=ST-1
 FINISH ELSE START 
 *LD_BLD0
 *LDB_LL
 *SWEQ_L =DR ,0,32
 *CYD_=0
 *LDA_TLINE+4
 *INCA_=1
 *MV_L =DR 
 *INCA_=-2; ! TO LAST SPACE
 *LSS_=32
BACK: *ICP_(DR )
 *JCC_7,<OUT>
 *INCA_=-1
 *J_<BACK>
OUT: *LSS_=10
 *INCA_=1
 *ST_(DR )
 *STD_ST
 *LSS_LS
 *ISB_TLINE+4
 *ST_LL
 FINISH 
END 
END 
ROUTINE COMPARE
ROUTINESPEC UP
LONGREAL ALIGN
INTEGER RA, RL, RP, RQ, RR, SSL, SC, RS, MARKER, ALT, PP, I, J, FAILNO
CONSTINTEGERARRAY OPMASK(0:7)=0,X'00350000',2,0(3),X'08008000',0;
SWITCH BIP(999:1045)
 IF INCLUDE HANDCODE=YES THEN START 
 I=ADDR(SYMBOL(1300))-4*1300
 *LSS_I
 *LUH_X'28001000'
 *ST_ALIGN
 *JLK_2
 *EXIT_-64
 FINISH 
SUBENTRY:
 RP=SYMBOL(P)
 RL=LEVEL
 IF P=SS START 
 I=CC(Q)
 IF TRTAB(I)#2 AND I#'F'+128 AND I#'G'+128 AND C 
 (I#'I'+128 OR CC(Q+1)#'F'+128) START 
 RQ=Q; RR=R; SSL=STRLINK; ALT=2; SC=LINE; P=P+1
 RS=SYMBOL(P); RA=SYMBOL(RS); ->UPR
 FINISH 
 FINISH 
 P=P+1; PP=P
 ->COMM
 ! ROUTINE REALLY STARTS HERE
BIP(999): ! REPEATING PHRASES
 A(RR)=ALT; P=PP; ! P BACK TO CURRENT PHRASE AGN
COMM: ! COMMON INITIALISE CODEING
 IF INCLUDE HANDCODE=NO THEN START 
 RQ=Q; ! RESET VALUES OF LINE&AR PTRS
 RR=R
 SSL=STRLINK; ! SAVE STRLINK IN CASE BACK-
 SC=LINE; ! -TRACKING ACROSS A RT CALL
 FINISH ELSE START 
 *LSQ_Q
 *ST_RQ
 FINISH 
 ALT=1; ! FIRST ALTERNATIVE TO BE TRIED
 IF INCLUDE HANDCODE=NO THEN START 
 RS=P
 RA=SYMBOL(P); ! RA TO NEXT PHRASE ALTERNATIVE
 FINISH ELSE START 
 *LB_P
 *STB_RS
 *LSS_(ALIGN+B )
 *ST_RA
 FINISH 
UPR: R=R+1
SUCC: ! SUCCESS ON TO NEXT ITEM
 IF INCLUDE HANDCODE=NO THEN START 
 RS=RS+1; ! RS=NEXT ALTERNATIVE MEANS THAT
 ! THIS ALT HAS BEEN COMPLETED SO
 ! EXIT WITH HIT=1
 IF RS#RA THEN ->NEXTBR
 FINISH ELSE START 
 *LB_RS
 *ADB_1
 *CPB_RA
 *JCC_7,<NEXTBR>
 FINISH 
BIP(1000):
 A(RR)=ALT
 HIT=1
 IF INCLUDE HANDCODE=NO THEN RETURN ELSE START 
 *J_TOS 
 FINISH 
NEXTBR: ! ONTO NEXT BRICK
 IF INCLUDE HANDCODE=NO THEN START 
 ITEM=SYMBOL(RS); ! NEXT BRICK IN THE CURRENT ALT
 IF ITEM<999 START 
 IF CC(Q)=ITEM THEN Q=Q+1 AND ->SUCC
 ->FAIL1
 FINISH 
 IF ITEM <1300 THEN ->BIP(ITEM)
 P=ITEM
 COMPARE
 FINISH ELSE START 
 *STB_RS
 *LSS_(ALIGN+B )
 *ICP_999
 *JCC_10,<NOTLIT>
 *LB_Q
 *ICP_(CC+B )
 *JCC_7,<FAIL1>
 *ADB_1
 *STB_Q
 *J_<SUCC>
NOTLIT:
 *ICP_1300
 *JCC_10,<NOTBIP>
 *ST_ITEM
 ->BIP(ITEM)
NOTBIP:
 *ST_P
 *LSQ_RA
 *SLSQ_RR
 *SLSQ_MARKER
 *ST_TOS 
 *JLK_<SUBENTRY>
 *LSQ_TOS 
 *ST_MARKER
 *LSQ_TOS 
 *ST_RR
 *LSQ_TOS 
 *ST_RA
 FINISH 
 IF HIT#0 THEN ->SUCC
 ->FAIL; ! PRESERVE FAILNO FROM RETURN
FAIL1: FAILNO=1; ! LEXICAL MISMATCH TYPE OF FAIL
FAIL: ! FAILURE - NOTE POSITION REACHD
!
! THIS SECTION IS EXECUTED SO OFTEN IT IS WORTH HANDCODEING
!
 IF RA=RP START ; ! TOTAL FAILURE NO ALT LEFT TO TRY
 HIT=0
 IF LEVEL#RL START 
 UP IF LEVEL>RL
 LEVEL=RL
 FINISH 
 IF INCLUDE HANDCODE=NO THEN RETURN ELSE START 
 *J_TOS 
 FINISH 
 FINISH 
 IF INCLUDE HANDCODE=NO THEN START 
 QMAX=Q AND ANALFAIL=FAILNO IF Q>QMAX
 FINISH ELSE START 
 *LSS_Q
 *ICP_QMAX
 *JCC_12,<MCL1>
 *ST_QMAX
 *LSS_FAILNO
 *ST_ANALFAIL
 FINISH 
MCL1:
 IF INCLUDE HANDCODE=NO THEN START 
 Q=RQ; ! RESET LINE AND A.R. POINTERS
 R=RR
 LINE=SC
 STRLINK=SSL
 RS=RA; ! MOVE TO NEXT ALT OF PHRASE
 RA=SYMBOL(RA)
 FINISH ELSE START 
 *LSQ_RQ
 *ST_Q
 *LB_RA
 *STB_RS
 *LSS_(ALIGN+B )
 *ST_RA
 FINISH 
 ALT=ALT+1
 ->UPR
BIP(1001): ! PHRASE NAME
BIP(1004): ! PHRASE OLDNAME
 IF LASTAT=Q THEN START 
 A(R)=LASTNAME
 Q=LASTEND
 ->UPR
 FINISH 
 ->FAIL1 UNLESS TRTAB(CC(Q))=2
 PNAME(ITEM-1004)
 ->SUCC IF HIT=1; FAILNO=2; 
 ->FAIL
BIP(1002): ! PHRASE INTEGER CONSTANT
BIP(1003): ! PHRASE CONST
 FAILNO=CONST(ITEM-1003)
 ->FAIL IF HIT=0
 IF CTYPE=2 START ; ! %REAL
 A(R)=2
 A(R+1)=INTEGER(ADDR(CVALUE))
 A(R+2)=INTEGER(ADDR(CVALUE)+4)
 R=R+3
 FINISH ELSE START 
 A(R)=1
 A(R+1)= S; R=R+2
 FINISH ; ->SUCC
BIP(1005): ! PHRASE COMMENT TEXT 
 S=0
 I=CC(Q)
 WHILE I#';' CYCLE 
 IF I&128#0 THEN S=1
 Q=Q+1; I=CC(Q)
 REPEAT 
 IF S#0 THEN WARN(1,0)
 Q=Q+1; ->SUCC
BIP(1006): ! PHRASE S=SEPARATOR
 J=Q-5
 IF CC(J+4)='N'+128 AND CC(J+3)='I'+128 C 
 AND CC(J+2)='G'+128 AND CC(J+1)='E'+128 C 
 AND CC(J)='B'+128 THEN ->SEP
 I=CC(Q)
 IF I=';' THEN Q=Q+1 AND ->SEP
 IF I='E'+128 AND CC(Q+1)='N'+128 C 
 AND CC(Q+2)='D'+128 THEN ->SEP
 ->FAIL1
SEP: ! SEPERATOR FOUND
 IF JROUND(LEVEL)#0 AND JROUND(LEVEL)&255=0 THEN UP
 ->SUCC
BIP(1007):
 S=0
 CYCLE ; ! PHRASE ENDTEXT=COMMENT TEXT
 WHILE ';'#CC(Q)#'E'+128 CYCLE 
 IF CC(Q)>128 AND S=0 THEN S=1 AND WARN(1,0)
 Q=Q+1
 REPEAT 
 ->SUCC IF CC(Q)=';'
 ->SUCC IF CC(Q+1)='N'+128 AND CC(Q+2)='D'+128
 ->SUCC IF CC(Q+1)='L'+128 AND CC(Q+2)='S'+128 C 
 AND CC(Q+3)='E'+128
 Q=Q+1
 REPEAT 
BIP(1008): ! PHRASE TEXTTEXT=BETWEEN QUOTES
 TEXTTEXT
 ->FAIL1 IF HIT=0; ->UPR
BIP(1009): ! PHRASE NAMELIST
BIP(1012): ! PHRASE OLD NAMELIST
 ! GIVES AR IN FORM NNAMES,NAME1,....NAMEN
 U=R; V=1; R=R+1
 ->FAIL1 UNLESS TRTAB(CC(Q))=2
 PNAME(ITEM-1012)
 IF HIT=0 THEN FAILNO=2 AND ->FAIL
 CYCLE 
 J=CC(Q)
 Q=Q+1
 EXIT UNLESS J=','
 I=CC(Q)
 PNAME(ITEM-1012)
 EXIT IF HIT=0; V=V+1
 REPEAT 
 Q=Q-1
 A(U)=V; ->SUCC
BIP(1010): ! PHRASE HOLE
 MARKER=R; ->UPR
BIP(1011): ! PHRASE MARK
 A(MARKER)=R-MARKER
 ->SUCC
BIP(1013): ! PHRASE UP STATEMENT COUNT
 LINE=LINE+1 WHILE CCLINES(LINE+1)<=Q
 A(R)=LINE; ->UPR
BIP(1014): ! PHRASE LETTER STRING
 I=CC(Q)
 ->FAIL1 UNLESS TRTAB(I)=2
 Q=Q+1 WHILE TRTAB(CC(Q))=2
 ->SUCC
BIP(1015): ! PHRASE DOWN=NEW TEXT LEVEL
 IF LEVEL>=2 THEN C 
 A(SET(LEVEL))=A(SET(LEVEL))+X'1000';! NOTE NESTED BLK
 LEVEL=LEVEL+1
 JROUND(LEVEL)=0
 RAL(LEVEL)=R; !RAL FOR LINKING LABELS
 A(R)=0; R=R+1
 FLAG(LEVEL)=R; ! FLAG FOR LINKING SCALARS
 A(R)=0; R=R+1
 L(LEVEL)=R; ! L FOR LINKING ARRAYS
 A(R)=0; R=R+1
 M(LEVEL)=R; ! M FOR LINKING SWITCHES
 A(R)=0; R=R+1
 NMDECS(LEVEL)=R; ! NMDECS FOR LINKING OWNS
 A(R)=0; R=R+1
 STACKBASE(LEVEL)=R; ! STACKBASE FOR LINKING PROCS
 A(R)=0; R=R+1
 SET(LEVEL)=R; ! A(SET(LEVEL)) COUNTS EMBEDDED LABS
 A(R)=0; R=R+1; ->SUCC
BIP(1016): ! PHRASE UP 1 TEXTUAL LEVEL
 IF JROUND(LEVEL)&255#0 THEN C 
 JROUND(LEVEL)=JROUND(LEVEL)-1 AND ->SUCC
 UP; ! ONE TEXTUAL LEVEL
 ->SUCC
BIP(1017): ! PHRASE SCALAR TYPE
 TYPE=A(R-2); ->SUCC UNLESS TYPE=4; ->FAIL1
BIP(1018): ! PHRASE DECLARE NAME
 I=A(R-1)
 J=NTYPE(I)
 IF J&31=LEVEL THEN START 
 FAILNO=4 AND ->FAIL C 
 UNLESS TYPE=J>>8&255 AND (TYPE>=128 OR TYPE=38)
 FINISH ELSE START 
 IF J#0 THEN PUSH(TAGS(I), J, DPOSN(I),0)
 NTYPE(I)=TYPE<<8!LEVEL!NAMES(LEVEL)<<16
 DPOSN(I)=R-1
 NAMES(LEVEL)=I
 FINISH 
 ->SUCC
BIP(1019): ! PHRASE TYPE=ARITHMETIC
 ->SUCC IF 1<=NTYPE(LASTNAME)>>8&7<=2
 IF NTYPE(LASTNAME)=0 THEN FAILNO=2 ELSE FAILNO=10; ->FAIL
BIP(1020): ! PHRASE TYPE=BOOLEAN
 ->SUCC IF NTYPE(LASTNAME)>>8&7=3
 IF NTYPE(LASTNAME)=0 THEN FAILNO=2 ELSE FAILNO=10; ->FAIL
BIP(1021): ! PHRASE ARRAYTYPE
 TYPE=A(R-2)+32
 TYPE=34 IF TYPE=36; ->SUCC
BIP(1022): ! PHRASE PROCTYPE
 TYPE=A(R-2)&3+128; ->SUCC
BIP(1023): ! PHRASE LINK SCALAR DECLNS
 IF LEVEL<=1 THEN QMAX=Q-1 AND FAILNO=9 AND ->FAIL
 A(FLAG(LEVEL))=R-FLAG(LEVEL)-1
 A(R)=0; FLAG(LEVEL)=R; 
 R=R+1; ->SUCC
BIP(1024): ! PHRASE LINK ARRAY DECLNS
 IF LEVEL<=1 THEN FAILNO=9 AND ->FAIL
 A(L(LEVEL))=R-L(LEVEL)-1
 A(R)=0; L(LEVEL)=R; 
 R=R+1; ->SUCC
BIP(1025): ! PHRASE CHKLPL(LOOK FOR :=)
 ->FAIL1 UNLESS TRTAB(CC(Q))=2
 I=Q
 I=I+1 WHILE ';'#CC(I)#':'
 IF CC(I)=':' AND CC(I+1)='=' THEN ->SUCC
 ->FAIL1
BIP(1026): ! PHRASE LABTYPE
 PASS2INF=PASS2INF!LABBYNAME; ! NOTE PRESENCE OF LAB PARAMETERS
 TYPE=6; ->SUCC
BIP(1043): ! PHRASE SWITCH BY NAME
 PASS2INF=PASS2INF!SWBYNAME; ! NOTE PRESENCE OF FORMAL SWITCH
BIP(1027): ! PHRASE SWTYPE
 TYPE=38; ->SUCC
BIP(1028): ! PHRASE STRTYPE
 TYPE=5; ->SUCC
BIP(1029): ! PHRASE CHK LAB
 I=Q
 I=I+1 WHILE TRTAB(CC(I))#0
 IF CC(I)=':' AND CC(I+1)#'=' START 
 IF CC(I+1)#'C'+128 OR CC(I+2)#'O'+128 OR C 
 CC(I+3)#'M'+128 THEN ->SUCC
 Q=I+1; ->FAIL1
 FINISH 
 ->FAIL1
BIP(1030): ! TYPE=ARR
 IF NTYPE(LASTNAME)>>8&32=0 THEN ->NOTARR
 ->SUCC IF CC(Q)='[' OR (CC(Q)='(' AND CC(Q+1)='/')
 I=DPOSN(LASTNAME)
 A(I)=A(I)!X'10000'
 ->SUCC
NOTARR:
 IF CC(Q)='[' OR (CC(Q)='(' AND CC(Q+1)='/') THEN C 
 FAILNO=3 AND QMAX=Q-1 ELSE FAILNO=1
 ->FAIL
BIP(1031): ! PHRASE LINK SWITCH DECLNS
 IF LEVEL<=1 THEN FAILNO=9 AND ->FAIL
 A(M(LEVEL))=R-M(LEVEL)-2
 A(R)=0; M(LEVEL)=R; 
 R=R+1; ->SUCC
BIP(1032): ! PHRASE LINK OWN DECLNS
 IF LEVEL<=1 THEN FAILNO=9 AND ->FAIL
 A(NMDECS(LEVEL))=R-NMDECS(LEVEL)
 A(R)=0; NMDECS(LEVEL)=R; 
 R=R+1; ->SUCC
BIP(1033): ! PHRASE LINK PROC STMNTS
 A(STACKBASE(LEVEL))=R-STACKBASE(LEVEL)-1
 A(R)=0; STACKBASE(LEVEL)=R; 
 R=R+1; ->SUCC
BIP(1034): ! PHRASE LINKLAB
 IF LEVEL<=1 THEN FAILNO=9 AND ->FAIL
 A(RAL(LEVEL))=R-RAL(LEVEL)-2
 A(R)=0; RAL(LEVEL)=R; 
 I=LEVEL-1
 WHILE I>=2 CYCLE 
 A(SET(I))=A(SET(I))+1
 I=I-1
 REPEAT 
 R=R+1; ->SUCC
BIP(1035): ! PHRASE NOMORE
 I=CC(Q)
 ->SUCC IF I=')' OR I=','
 ->FAIL1
BIP(1036): ! PHRASE CMPND
 I=CC(Q)
 ->FAIL IF LEVEL <= 1; !* UKC
 ->FAIL1 UNLESS I=';' OR I='E'+128 OR CC(Q-1)='N'+128
 JROUND(RL)=JROUND(RL)+1
 ->SUCC
BIP(1037): ! PHRASE UP AT (NEXT) SEP
 JROUND(LEVEL)=JROUND(LEVEL)+256
 ->SUCC
BIP(1038): ! P(PLUS')='+','-',0
 I=CC(Q)
 IF I='-' THEN A(R)=2 AND Q=Q+1 ELSE A(R)=3
 IF I='+' THEN Q=Q+1
 ->UPR
BIP(1039): ! P(OP)=^,**,+,-,*,/,%DIV,%POWER
 I=CC(Q)
 ->FAIL1 UNLESS OPMASK(I>>5)&X'80000000'>>(I&31)#0
 Q=Q+1
 IF I='-' THEN A(R)=4 AND ->UPR
 IF I='+' THEN A(R)=3 AND ->UPR
 J=CC(Q)
 IF I='*' THEN START 
 IF J#'*' THEN A(R)=5 AND ->UPR
 Q=Q+1; A(R)=2; ->UPR
 FINISH 
 IF I='/' THEN A(R)=6 AND ->UPR
 IF I='^' THEN A(R)=1 AND ->UPR
 IF I='D'+128 AND J='I'+128 AND CC(Q+1)='V'+128 THEN C 
 Q=Q+2 AND A(R)=7 AND ->UPR
 IF I='P'+128 AND J='O'+128 AND CC(Q+1)='W'+128 AND C 
 CC(Q+2)='E'+128 AND CC(Q+3)='R'+128 THEN C 
 Q=Q+4 AND A(R)=8 AND ->UPR
 ->FAIL1
BIP(1040): ! PHRASE CHECKSC
 ->SUCC IF CC(Q)=';'; ->FAIL1
BIP(1041): ! PHRASE LEFT SQUARE BRACKET
 I=CC(Q)
 IF I='[' THEN Q=Q+1 AND ->SUCC
 UNLESS I='(' AND CC(Q+1)='/' THEN ->FAIL1
 Q=Q+2; ->SUCC
BIP(1042): ! PHRASE RIGHT SQUARE BRACKET
 I=CC(Q)
 IF I=']' THEN Q=Q+1 AND ->SUCC
 UNLESS I='/' AND CC(Q+1)=')' THEN ->FAIL1
 Q=Q+2; ->SUCC
BIP(1044): ! PHRASE TYPENOTBOOLEAN
 ->SUCC UNLESS NTYPE(LASTNAME)>>8&7=3 AND C 
 NTYPE(LASTNAME)&31=LEVEL
 FAILNO=10; ->FAIL
BIP(1045): ! PHRASE TYPENOT ARITH
 ->SUCC UNLESS 1<=NTYPE(LASTNAME)>>8&7<=2 AND C 
 NTYPE(LASTNAME)&31=LEVEL
 FAILNO=10; ->FAIL
ROUTINE UP
!***********************************************************************
!* COME UP A TEXTUAL LEVEL. INVOLVES UNDECLARING NAMES *
!***********************************************************************
 I=NAMES(LEVEL)
 WHILE 0<=I<=NNAMES CYCLE 
 J=NTYPE(I)
 NTYPE(I)=0
 IF TAGS(I)#0 THEN POP(TAGS(I), NTYPE(I), DPOSN(I),ITEM)
 I=J>>16
 REPEAT 
 NAMES(LEVEL)=-1
 LEVEL=LEVEL-1
END ; ! OF ROUTINE UP
END ; !OF ROUTINE 'COMPARE'
ROUTINE PNAME(INTEGER MODE)
!***********************************************************************
!* MODE=0 FOR OLD NAME(ALREADY IN DICT), MODE=1 FOR NEW NAME *
!***********************************************************************
CONSTINTEGERARRAY HASH(0:7)=71,47,97,79,29,37,53,59;
INTEGER JJ, KK, LL, FQ, FS, S, TT, I
IF INCLUDE HANDCODE=YES THEN START 
 LONGINTEGER DRDES,ACCDES
FINISH 
 HIT=0; FQ=Q; FS=CC(Q)
 RETURN UNLESS TRTAB(FS)=2; ! 1ST CHAR MUST BE LETTER
 TT=1; LETT(NEXT+1)=FS; JJ=71*FS
 IF INCLUDE HANDCODE=NO THEN START 
 CYCLE 
 Q=Q+1
 I=CC(Q)
 EXIT IF TRTAB(I)=0
 JJ=JJ+HASH(TT)*I IF TT<=7
 TT=TT+1
 LETT(NEXT+TT)=I
 REPEAT 
 FINISH ELSE START 
CYC:
 *LB_Q
 *ADB_1
 *STB_Q
 *LB_(CC+B )
 *LSS_(TRTAB+B )
 *JAT_4,<EXIT>
 *STB_I
 *LSS_B ; ! I TO ACC
 *LB_TT
 *CPB_7
 *JCC_2,<SKIP>
 *IMY_(HASH+B )
 *IAD_JJ
 *ST_JJ
SKIP:
 *ADB_1
 *STB_TT
 *LSS_I
 *ADB_NEXT
 *ST_(LETT+B )
 *J_<CYC>
EXIT:
 FINISH 
 LETT(NEXT)=TT; ! INSERT LENGTH
 T=TT
 S=T+1
 FAULT(103,0) IF NEXT+S>DSIZE;!DICTIONARY OVERFLOW
 JJ=(JJ+113*TT)&NNAMES
 IF INCLUDE HANDCODE=NO THEN START 
 CYCLE KK=JJ, 1, NNAMES
 LL=WRD(KK)
 ->HOLE IF LL=0; ! NAME NOT KNOWN
 ->FND IF STRING(ADDR(LETT(NEXT)))=STRING(ADDR(LETT(LL)))
 REPEAT 
 CYCLE KK=0,1,JJ
 LL=WRD(KK)
 ->HOLE IF LL=0; ! NAME NOT KNOWN
 ->FND IF STRING(ADDR(LETT(NEXT)))=STRING(ADDR(LETT(LL)))
 REPEAT 
 FINISH ELSE START 
 *LDTB_X'18000000'
 *LDB_S
 *LDA_LETT+4
 *STD_DRDES
 *INCA_NEXT
 *STD_ACCDES
 *LB_JJ
CYC1:
 *STB_KK
 *LB_(WRD+B )
 *JAT_12,<HOLE>
 *LSD_ACCDES
 *LD_DRDES
 *INCA_B 
 *CPS_L =DR 
 *JCC_8,<FND>
 *LB_KK
 *CPIB_NNAMES
 *JCC_7,<CYC1>
 *LB_0
CYC2:
 *STB_KK
 *LB_(WRD+B )
 *JAT_12,<HOLE>
 *LSD_ACCDES
 *LD_DRDES
 *INCA_B 
 *CPS_L =DR 
 *JCC_8,<FND>
 *LB_KK
 *CPIB_JJ
 *JCC_7,<CYC2>
 FINISH 
 FAULT(104, 0); ! TOO MANY NAMES
HOLE: IF MODE=0 THEN ->XIT
 WRD(KK)=NEXT; NEXT=NEXT+S
FND: LASTAT=FQ; HIT=1; LASTNAME=KK
 A(R)=LASTNAME
 R=R+1
 LASTEND=Q
XIT:
END ; ! OF ROUTINE PNAME
 INTEGERFN CONST(INTEGER MODE)
!***********************************************************************
!* MODE=0 FOR NORMAL MODE=2 FOR EXPONENT (IE INTEGER CONSTANTS) *
!***********************************************************************
INTEGER Z, I
LONGLONGREAL X,CV
 CONSTLONGLONGREAL TEN=R'41A00000000000000000000000000000'
 CV=0; I=CC(Q); CTYPE=1; HIT=0
 S=0; ->N IF M'0'<=I<=M'9'
 ->DOT IF I='.' AND MODE=0
 ! 1 DIDT MIN
 IF (I='&' OR I='@') AND MODE=0 THEN CV=1 AND ->ALPHA
 RESULT =1
OFLOW: RESULT =8
N: I=I&15; CV=TEN*CV+I
 Q=Q+1; I=CC(Q)
 ->N IF M'0'<=I<=M'9'
 ->ALPHA UNLESS MODE=0 AND I='.'
DOT: Q=Q+1; X=TEN; CTYPE=2
 I=CC(Q)
 RESULT =5 UNLESS '0'<=I<='9'; ! '23.' NOT VALID IN ALGOL
 WHILE '0'<=I<='9' CYCLE 
 CV=CV+(I&15)/X
 X=TEN*X; Q=Q+1
 I=CC(Q)
 REPEAT 
ALPHA: ! TEST FOR EXPONENT
 ->FIX UNLESS MODE=0 AND (I='&' OR I='@')
 Q=Q+1; X=CV; CTYPE=2
 Z=1; UNLESS '+'#CC(Q)#'-' START 
 Z=-1 IF CC(Q)='-'; Q=Q+1
 FINISH 
 I=CONST(2); RESULT =6 IF HIT=0; S=S*Z
 HIT=0; CTYPE=2
 IF S=-99 THEN CV=0 ELSE START 
 CV=X
 IF INCLUDE HANDCODE=YES THEN START 
 *MPSR_X'8080'; ! MASK OUT OFLOW
 FINISH 
 WHILE S>0 CYCLE 
 S=S-1
 IF INCLUDE HANDCODE=YES THEN START 
 CV=CV*TEN
 *JAT_15,<OFLOW>; ! OVERFLOWED
 FINISH ELSE CV=CV*TEN
 REPEAT 
 WHILE S<0 AND CV#0 CYCLE 
 S=S+1
 CV=CV/TEN
 REPEAT 
 FINISH 
FIX: ! SEE IF IT IS INTEGER
 IF INCLUDE HANDCODE=NO THEN CVALUE=CV ELSE START 
 *LSD_X'7F00000000000000'
 *AND_CV
 *SLSD_X'0080000000000000'
 *AND_CV+8
 *LUH_TOS 
 *RAD_CV
 *STUH_CVALUE
 FINISH 
 IF CTYPE#1 THEN HIT=1 AND RESULT =0
 IF CVALUE<=IMAX THEN START 
 S=INT(CVALUE)
 CTYPE=1; HIT=1
 RESULT =0
 FINISH 
 RESULT =7
END 
ROUTINE TEXTTEXT
CONSTINTEGER TXT1='<'
INTEGER S, J, BR, FIRST, LAST, I, AAR
 S=R; R=R+2; BR=1; HIT=0
 I=CC(Q)
 RETURN UNLESS (I=TXT1 AND QFLAG=0) OR I=123
 ! FAIL UNLESS INITIAL QUOTE
 FIRST=I; LAST=FIRST+2
 Q=Q+1; J=0; AAR=ADDR(A(R))
 UNTIL BR=0 CYCLE 
 I=CC(Q)
 IF I=FIRST THEN BR=BR+1
 IF I=LAST THEN BR=BR-1
 IF I>128 AND CC(Q-1)<128 THEN C 
 BYTE INTEGER(AAR+J)=KYCHAR1 AND J=J+1
 IF I<128 AND CC(Q-1)>128 THEN C 
 BYTE INTEGER(AAR+J)=KYCHAR2 AND J=J+1
 BYTE INTEGER(AAR+J)=I
 J=J+1; Q=Q+1
 IF Q>LENGTH THEN FAULT(106,0)
 REPEAT 
 IF J>256 THEN WARN(5,0) AND J=256
 J=J-1
 R=R+(J+3)>>2
 A(S+1)=J
 A(S)=STRLINK; STRLINK=S
 HIT=1
END 
BEND:END ;! END OF FIRST 2 PASSES
 IF LEVEL>1 THEN FAULT(15, 0)
 I=0
 NEWLINE
 IF FAULTY=0 THEN START 
 WRITE(LASTLINE-1, 5)
 PRINT STRING(' LINES ANALYSED
')
 FINISH ELSE START 
 PRINTSTRING('
CODE GENERATION NOT ATTEMPTED
')
 COMREG(24)=8
 COMREG(47)=FAULTY
 STOP 
 FINISH 
BEGIN 
!***********************************************************************
!* FINAL OR CODE GENERATING PASS *
!***********************************************************************
ROUTINESPEC CNOP(INTEGER I, J)
ROUTINESPEC PCLOD(INTEGER FROM, TO)
ROUTINESPEC PCONST(INTEGER X)
ROUTINESPEC PSF1(INTEGER OPCODE,K,N)
ROUTINESPEC PF1(INTEGER OPCODE,KP,KPP,N)
ROUTINESPEC PSORLF1(INTEGER OPCODE,KP,KPP,N)
ROUTINESPEC PF2(INTEGER OPCODE,H,Q,N,MASK,FILLER)
ROUTINESPEC PF3(INTEGER OPCODE,MASK,KPPP,N)
ROUTINESPEC PLANT(INTEGER VALUE)
ROUTINESPEC PLUG(INTEGER I, J, K)
ROUTINESPEC CODEOUT
ROUTINESPEC NOTE CREF(INTEGER CA)
INTEGERFNSPEC PARAM DES(INTEGER PREC)
INTEGERFNSPEC SPECIAL CONSTS(INTEGER WHICH)
ROUTINESPEC STORE CONST(INTEGERNAME D,INTEGER L,C1,C2)
ROUTINESPEC DUMP CONSTS
ROUTINESPEC PROLOGUE
ROUTINESPEC EPILOGUE
ROUTINESPEC CSS(INTEGER P)
ROUTINESPEC ABORT
IF ALLOW CODELIST=YES THEN START 
 ROUTINESPEC RECODE(INTEGER START, FINISH, CA)
 ROUTINESPEC PRINT USE
FINISH 
INTEGERARRAY REGISTER, OLINK, GRUSE, GRAT, GRINF(0:7)
BYTEINTEGERARRAY CODE, GLABUF(0:268)
INTEGERARRAY DESADS,PLABS,PLINK(0:31),DVHEADS(0:12)
INTEGERARRAY AUXSBASE,LABEL,DIAGINF,DISPLAY(0:MAXLEVELS)
INTEGERARRAY AVL WSP(1:4,0:MAXLEVELS)
INTEGERARRAYFORMAT CF(0:12*NNAMES)
INTEGERARRAYNAME CTABLE
 CYCLE I=0, 1, 7
 REGISTER(I)=0; GRUSE(I)=0
 GRAT(I)=0; GRINF(I)=0
 REPEAT 
 CYCLE I=0, 1, MAXLEVELS
 NAMES(I)=-1
 DIAGINF(I)=0; DISPLAY(I)=0
 AUXSBASE(I)=0; LABEL(I)=0
 NMDECS(I)=0
 DVHEADS(I)=0 IF I<=12
 CYCLE J=1,1,4
 AVL WSP(J,I)=0
 REPEAT 
 REPEAT 
 CTABLE==ARRAY(ADDR(ASLIST(1)),CF)
 LINE=0
 PROLOGUE
 NEXTP=8
 LEVEL=1; RLEVEL=0
 CYCLE 
 IF ALLOW CODELIST=YES AND DCOMP#0 AND CA>CABUF THEN C 
 CODEOUT AND PRINT USE
 I=NEXTP
 NEXTP=NEXTP+A(NEXTP)
 LINE=A(I+1)
 EXIT IF LINE=0
 CSS(I+2)
 REPEAT 
 IF FAULTY=0=CPRMODE THEN LINE=LASTLINE-1 AND FAULT(57,0)
 LINE=9999
 EPILOGUE
!***********************************************************************
!* PASS INFORMATION TO LPUT TO ENABLE IT TO GENERATE THE *
!* LOADER DATA AND COMPLETE THE PROGRAM FILE. *
!***********************************************************************
 GLACA=(GLACA+7)&(-8)
 USTPTR=(USTPTR+7)&(-8)
 CNOP(0, 8)
 CODE OUT
 I=(PARMDIAG<<1!PARMLINE)<<1!PARMTRCE
!
! ALGOL LANGUAGE VALUE IS 5. 6 IS RESERVED FOR ANY OPTIMISED PROGRAM
!
 FIXED GLA(4)=(6-PARMTRCE)<<24!1<<16!(CPRMODE&1)<<8!I
 I=GLACA-GLACABUF
 IF INHCODE=0 THEN START 
 LPUT(2, I, GLACABUF, ADDR(GLABUF(0))) UNLESS I=0
 GLACABUF=GLACA; GLACURR=0; ! DUMP CONSTS MAY PLUG GLA
 ! BACK OF GLAP
 LPUT(2, N0<<2, 0, ADDR(FIXED GLA(0)));! FRONT OF GLAP
 I=X'E2E2E2E2'
 LPUT(4, 4, SSTL, ADDR(I))
 LPUT(19, 2, 12, 4); ! RELOCATE POINTER TO CST
 LPUT(19, 2, 8, 5); ! RELOCATE PTR TO GLAST
 FINISH 
 DUMP CONSTS
 SSTL=(SSTL+11)&(-8)
 NEWLINE
 IF VMEB=YES THEN FAULTMK(8)
 PRINTSTRING( "CODE")
 WRITE(CA, 6); PRINTSTRING( " BYTES GLAP")
 WRITE(GLACA, 3); PRINTSTRING( "+")
 WRITE(USTPTR, 1); PRINTSTRING( " BYTES DIAG TABLES")
 WRITE(SSTL, 3); PRINTSTRING( " BYTES
TOTAL")
 REGISTER(0)=CA; REGISTER(1)=GLACA
 REGISTER(2)=0
 REGISTER(3)=SSTL
 REGISTER(4)=USTPTR
 K=CA+GLACA+SSTL+USTPTR; REGISTER(5)=K
 WRITE(K, 5); PRINTSTRING( " BYTES")
 NEWLINE
 IF FAULTY=0 THEN START 
 WRITE(LASTLINE-1,7); PRINTSTRING(" LINES COMPILED")
 COMREG(47)=LASTLINE-1; ! NO OF LINES FOR SUMMARY
 FINISH ELSE START 
 PRINT STRING("PROGRAM CONTAINS"); WRITE(FAULTY,2)
 PRINT STRING(" FAULT"); PRINT SYMBOL('S') IF FAULTY>1
 COMREG(47)=FAULTY
 FINISH 
 NEWLINES(2)
 I=0; I=8 IF FAULTY#0
 COMREG(24)=I
 IF INHCODE=0 THEN LPUT(7, 24, 0, ADDR(REGISTER(0)))
 ! SUMMARY INFO..REGISTER AS BUF
! PPROFILE
 STOP 
ROUTINE ABORT
 PRINTSTRING( '
**************** ABORT******************** ABORT *******')
 IF ALLOW CODELIST=YES THEN START 
 RECODE(ADDR(CODE(0)), ADDR(CODE(PPCURR)), CABUF) C 
 UNLESS CA=CABUF
 PRINT USE
 FINISH 
 MONITOR ; STOP 
END 
!
!***********************************************************************
!* IMP CODE PLANTING ROUTINES *
!* CODE AND GLAP ARE PUT INTO THE BUFFERS 'CODE,GLABUF(0:268)' *
!* BY A NUMBER OF TRIVIAL ROUTINES.LPUT IS CALLED TO ADD THE *
!* BUFFER TO THE OUTPUT FILE. THE BUFFERS ARE BASICALLY 0:255 *
!* WITH A 12-BYTE MARGIN TO MINIMISE THE NUMBER OF TESTS FOR *
!* THE BUFFER FULL CONDITION *
!* *
!* PPCURR(GLACURR) IS THE BUFFER POINTER *
!* CA(GLACA) IS THE RELATIVE ADDRESS OF THE NEXT BYTE *
!* CABUF(GLACABUF) IS CA(GLACA) FOR START OF BUFFER *
!***********************************************************************
IF ALLOW CODELIST=YES THEN START 
ROUTINE RECODE(INTEGER S,F,AD)
 IF S#F START 
 IF VMEB=YES THEN FAULTMK(4);! START OF CODE
 PRINTSTRING('
CODE FOR LINE'); WRITE(LINE,5)
 NCODE(S,F,AD)
 IF VMEB=YES THEN FAULTMK(1);! BACK TO NORMAL
 FINISH 
END 
FINISH 
ROUTINE CODEOUT
 IF PPCURR>0 THEN START 
 IF ALLOW CODELIST=YES AND DCOMP#0 THEN C 
 RECODE(ADDR(CODE(0)), ADDR(CODE(PPCURR)), CABUF)
 LPUT(1, PPCURR, CABUF, ADDR(CODE(0))) IF INHCODE=0
 PPCURR=0; CABUF=CA
 FINISH 
END 
ROUTINE PLANT(INTEGER HALFWORD)
!***********************************************************************
!* ADD A HALF WORD OF BINARY TO THE BUFFER *
!***********************************************************************
 IF INCLUDE HANDCODE=NO THEN START 
 CODE(PPCURR)<-HALFWORD>>8
 CODE(PPCURR+1)<-HALFWORD
 PPCURR=PPCURR+2
 FINISH ELSE START 
 *LDA_CODE+4
 *LDTB_X'58000002'
 *LB_PPCURR
 *LSS_HALFWORD
 *ST_(DR +B )
 *ADB_2
 *STB_PPCURR
 FINISH 
 CA=CA+2
 CODEOUT IF PPCURR>=256
END 
ROUTINE PCONST(INTEGER WORD)
!***********************************************************************
!* ADD A WORD OF BINARY TO THE BUFFER *
!***********************************************************************
INTEGER I
 IF INCLUDE HANDCODE=N0 THEN START 
 CYCLE I=24,-8,0
 CODE(PPCURR)=WORD>>I&255
 PPCURR=PPCURR+1
 REPEAT 
 FINISH ELSE START 
 *LDA_CODE+4
 *LDTB_X'58000004'
 *LSS_WORD
 *LB_PPCURR
 *ST_(DR +B )
 *ADB_4
 *STB_PPCURR
 FINISH 
 CA=CA+4
 CODE OUT IF PPCURR>=256
END 
ROUTINE PSF1(INTEGER OPCODE,K,N)
!***********************************************************************
!* PLANT THE HALFWORD FORMS OF PRIMARY FORMAT NR INSTRNS *
!* IF N IS TOO LARGE FOR THE SHORT FORM PF1 IS CALLED TO PLANT *
!* THE CORRESPONDING LONG FORM *
!***********************************************************************
INTEGER KPP
! ABORT %UNLESS 0<=K<=2 %AND OPCODE&1=0
 IF (K=0 AND -64<=N<=63) OR (K#0 AND 0<=N<=511) START 
 IF K#0 THEN N=N//4
 IF INCLUDE HANDCODE=NO THEN START 
 CODE(PPCURR)=OPCODE!K>>1
 CODE(PPCURR+1)=(K&1)<<7!N&127
 PPCURR=PPCURR+2
 FINISH ELSE START 
 *LSS_OPCODE
 *USH_1
 *OR_K
 *USH_7
 *SLSS_N
 *AND_127
 *LB_PPCURR
 *OR_TOS 
 *LDA_CODE+4
 *LDTB_X'58000002'
 *ST_(DR +B )
 *ADB_2
 *STB_PPCURR
 FINISH 
 CA=CA+2
 CODEOUT IF PPCURR>=256
 FINISH ELSE START 
 IF K=0 THEN KPP=0 ELSE KPP=2
 PF1(OPCODE,K>>1<<1,KPP,N)
 FINISH 
END 
ROUTINE PF1(INTEGER OPCODE,KP,KPP,N)
!***********************************************************************
!* PLANT THE NORMAL FORMS OF PRIMARY FORMAT INSTRNS(IE THOSE *
!* WHICH DO NOT DEPEND ON THE SIZE OF N) *
!***********************************************************************
INTEGER INC
! ABORT %UNLESS 0<=KP<=3 %AND 0<=KPP<=7 %AND OPCODE&1=0
 INC=2
 IF KPP=PC THEN START 
 IF N<0 THEN N=N&X'7FFFFFFF' AND NOTE CREF(CA)
 N=(N-CA)//2
 FINISH 
 IF (1<<KPP)&B'101100'#0 THEN N=N//4
 IF INCLUDE HANDCODE=NO THEN START 
 CODE(PPCURR)=OPCODE!1
 CODE(PPCURR+1)=X'80'!KP<<5!KPP<<2!(N>>16&3)
 CODE(PPCURR+2)=N>>8&255
 CODE(PPCURR+3)=N&255
 FINISH ELSE START 
 *LSS_OPCODE
 *USH_1
 *OR_3
 *USH_2
 *OR_KP
 *USH_3
 *OR_KPP
 *USH_18
 *SLSS_N
 *AND_X'3FFFF'
 *OR_TOS 
 *LDTB_X'58000004'
 *LDA_CODE+4
 *LB_PPCURR
 *ST_(DR +B )
 FINISH 
 IF KPP<=5 THEN INC=4
 PPCURR=PPCURR+INC
 CA=CA+INC
 CODEOUT IF PPCURR>=256
END 
ROUTINE PSORLF1(INTEGER OPCODE,KP,KPP,N)
!***********************************************************************
!* AS PF1 BUT CUT VALID FORMS TO SHORT FORM *
!***********************************************************************
INTEGER INC
 INC=2
 IF (KPP=0=KP AND -64<=N<=63) OR C 
 (KPP=LNB AND KP&1=0 AND 0<=N<=511) START 
 IF KPP=LNB THEN KP=1+KP>>1
 IF KP#0 THEN N=N//4
 IF INCLUDE HANDCODE=NO THEN START 
 CODE(PPCURR)=OPCODE!KP>>1
 CODE(PPCURR+1)=(KP&1)<<7!(N&127)
 FINISH ELSE START 
 *LSS_OPCODE
 *USH_1
 *OR_KP
 *USH_7
 *SLSS_N
 *AND_127
 *LB_PPCURR
 *OR_TOS 
 *LDA_CODE+4
 *LDTB_X'58000002'
 *ST_(DR +B )
 FINISH 
 FINISH ELSE START 
 IF KPP=PC THEN START 
 IF N<0 THEN N=N&X'7FFFFFFF' AND NOTE CREF(CA)
 N=(N-CA)//2
 FINISH 
 IF (1<<KPP)&B'101100'#0 THEN N=N//4
 IF INCLUDE HANDCODE=NO THEN START 
 CODE(PPCURR)=OPCODE!1
 CODE(PPCURR+1)=((4!KP)<<3!KPP)<<2!(N>>16&3)
 CODE(PPCURR+2)=N>>8&255
 CODE(PPCURR+3)=N&255
 FINISH ELSE START 
 *LSS_OPCODE
 *USH_1
 *OR_3
 *USH_2
 *OR_KP
 *USH_3
 *OR_KPP
 *USH_18
 *SLSS_N
 *AND_X'3FFFF'
 *OR_TOS 
 *LDTB_X'58000004'
 *LDA_CODE+4
 *LB_PPCURR
 *ST_(DR +B )
 FINISH 
 IF KPP<=5 THEN INC=4
 FINISH 
 CA=CA+INC; PPCURR=PPCURR+INC
 CODEOUT IF PPCURR>=256
END 
ROUTINE PF2(INTEGER OPCODE,H,Q,N,MASK,FILLER)
!***********************************************************************
!* PLANT SECONDARY(STORE TO STORE) FORMAT INSTRNS *
!* THESE MAY BE 16 OR 32 BIT DEPENDING ON Q *
!***********************************************************************
! ABORT %UNLESS 0<=H<=1 %AND 0<=Q<=1 %AND 0<=N<=127 %C
 AND OPCODE&1=0
 PLANT(OPCODE<<8!H<<8!Q<<7!N)
 IF Q#0 THEN PLANT(MASK<<8!FILLER)
END 
ROUTINE PF3(INTEGER OPCODE,MASK,KPPP,N)
!***********************************************************************
!* PLANT THE TERTIARY(JUMP) FORMAT INSTRUCTIONS *
!***********************************************************************
! ABORT %UNLESS 0<=MASK<=15 %AND 0<=KPPP<=7 %AND OPCODE&1=0
 IF KPPP=PC THEN START 
 IF N<0 THEN N=N&X'7FFFFFFF' AND NOTE CREF(CA)
 N=(N-CA)//2
 FINISH 
 CODE(PPCURR)=OPCODE!MASK>>3&1
 CODE(PPCURR+1)=(MASK&7)<<5!KPPP<<2!(N>>16&3)
 PPCURR=PPCURR+2
 CA=CA+2
 IF KPPP<=5 THEN START 
 CODE(PPCURR)=N>>8&255
 CODE(PPCURR+1)=N&255
 PPCURR=PPCURR+2; CA=CA+2
 FINISH 
 CODEOUT IF PPCURR>=256
END 
ROUTINE NOTE CREF(INTEGER CA)
!***********************************************************************
!* NOTE THAT A (PC+N) INSTRUCTION HAS N RELATIVE TO CONST TABLE *
!* NOT REATIVE TO CODE. REMEMBER THE ADDRESS OF THE INSTRUCTION *
!* SO THAT AN LPUT(18) CORRECTION CAN BE MADE AT END OF COMPILATION *
!***********************************************************************
RECORDNAME CELL (LISTF)
 CELL==ASLIST(CREFHEAD)
 IF CREFHEAD=0 OR CELL_S3#0 THEN C 
 PUSH(CREFHEAD,CA,0,0) AND RETURN 
 IF CELL_S2=0 THEN CELL_S2=CA ELSE CELL_S3=CA
END 
ROUTINE PCLOD(INTEGER FROM, TO)
!***********************************************************************
!* PLANT A SERIES OF INTRUNS FROM ARRAY FIXED CODE *
!***********************************************************************
INTEGER I,T,B
CONSTINTEGERARRAY FIXED CODE(0:127)= C 
 X'7B985398',X'18041C01',
 X'5D984998',X'5B987E84',
 X'6C091FCC',X'000A1B98',
 M'FREE',0,
 X'0580000B',X'63985F98',
 X'73986F9C',X'2A04779C',
 X'B1800081',X'49981B98',
 X'00000000',X'5F98E398',
 X'E87EE001',X'43986F98',
 X'49981B98',0,
 X'49987998',X'180463A0',
 X'000443A0',X'0002420A',
 X'43DC4998',X'7E846C09',
 X'1FCC000A',M'FREE',
 M'FREE', M'FREE',
 M'FREE', M'FREE',
 M'FREE', M'FREE',
 M'FREE',M'FREE',
 M'FREE',X'5D98738C',
 X'00051414',X'59986C0A',
 X'338040C0',0,
 X'7E807F8C',X'00046485',
 X'499879CC',X'000C63DC',
 X'48866289',X'E8658A07',
 X'E79C0240',X'00320280',
 X'00188A03',X'EA044285',
 X'8B81FFFF',X'EB98499C',
 X'E08649DC',X'E7A00002',
 X'02400044',X'779C7398',
 X'12007286',X'B3006685',
 X'38006201',X'E81BE089',
 X'48858B81',X'FFFF499C',
 X'EA08E086',X'49DCE7A0',
 X'00020240',X'002D2201',
 X'63E80009',X'A80049E8',
 X'00050783',X'FFFA6685',
 X'38006201',X'E81BE489',
 X'48858B81',X'FFFF499C',
 X'EA04E086',X'49DCE7A0',
 X'00020240',X'00152201',
 X'65E80009',0,
 X'F837F849',X'5B98B99C',
 X'2A04E99C',X'32117B98',
 X'49E80005',X'0783FFF1',
 X'66853800',0,
 X'7B987998',X'5B985998',
 X'45980440',X'00350600',
 X'00074598',X'06200030',
 X'65981B98',X'45984998',
 X'0440001A',X'F837F849',
 X'B99C2A04',X'26400340',
 X'00037A40',X'E99C4B9C',
 X'02E0000E',X'6E7E499C',
 X'6201A800',X'07800005',
 X'6E7E1B98',X'5998FB98',
 X'247E1B98',X'65984598',
 X'18044998',X'7E846C07',
 M'FREE',X'FB981804',
 X'49987E84',X'6C071A01',
 X'5D984998',X'5B98359C',
 X'20105B98',X'4D983798',
 X'7DA00004',M'FREE',
 X'31987F98',X'33987B98',
 X'61987D98',X'3A001A01';
 B=(TO-FROM+1)*4
 B=B-2 IF FIXED CODE(TO)&X'FFFF'=X'1A01'
 CODE OUT IF PPCURR+B>=256
 T=ADDR(FIXED CODE(FROM))
 IF INCLUDE HANDCODE=NO THEN START 
 CYCLE I=0,1,B-1
 CODE(PP CURR)=BYTEINTEGER(T+I)
 PP CURR=PP CURR+1
 REPEAT 
 FINISH ELSE START 
 *LDTB_X'18000000'
 *LDB_B
 *LDA_T
 *CYD_0
 *LDA_CODE+4
 *INCA_PPCURR
 *MV_L =DR 
 PPCURR=PPCURR+B
 FINISH 
 CA=CA+B
END 
ROUTINE CNOP(INTEGER I, J)
 PLANT(X'1A01') WHILE CA&(J-1)#I;! JUNC *+1
END 
ROUTINE PGLA(INTEGER BDRY, L, INF ADR)
INTEGER I, J
 J=GLACA; GLACA=(J+BDRY-1)&(-BDRY)
 GLACURR=GLACURR+GLACA-J; ! COMPLETE THE ROUNDING
 IF L+GLACURR>256 THEN START 
 IF INHCODE=0 C 
 THEN LPUT(2, GLACURR, GLACABUF, ADDR(GLABUF(0)))
 GLACURR=0; GLACABUF=GLACA
 FINISH 
 IF INCLUDE HANDCODE=NO THEN START 
 CYCLE I=0,1,L-1
 GLABUF(GLACURR+I)=BYTE INTEGER(I+INF ADR)
 REPEAT 
 FINISH ELSE START 
 *LDTB_X'58000004'
 *LDB_L
 *LDA_INFADR
 *CYD_0
 *LDA_GLACURR
 *INCA_GLABUF+4
 *MV_L =DR 
 FINISH 
 GLACURR=GLACURR+L
 GLACA=GLACA+L
END 
ROUTINE PLUG(INTEGER AREA, AT, VALUE)
!***********************************************************************
!* WRITE ONE WORD INTO OBJECT FILE OUT OF SEQUENCE *
!***********************************************************************
INTEGER RELAD, BUFAD
 IF AREA=2 THEN BUFAD=ADDR(GLABUF(0)) AND RELAD=AT-GLACABUFC 
 ELSE BUFAD=ADDR(CODE(0)) AND RELAD=AT-CABUF
 IF RELAD>=0 AND AREA<=2 THEN START 
 IF INCLUDE HANDCODE=NO THEN START 
 CYCLE I=0,1,3
 BYTEINTEGER(RELAD+BUFAD+I)<-VALUE>>((3-I)<<3)
 REPEAT 
 FINISH ELSE START 
 *LDA_RELAD
 *INCA_BUFAD
 *LSS_VALUE
 *LDTB_X'58000004'
 *ST_(DR )
 FINISH 
 FINISH ELSE START 
 IF RELAD=-2 THEN CODEOUT
 IF INHCODE=0 THEN LPUT(AREA, 4, AT, ADDR(VALUE))
 IF ALLOW CODELIST=YES AND DCOMP#0 AND AREA=1 THEN C 
 NCODE(ADDR(VALUE),ADDR(VALUE)+4,AT)
 FINISH 
END 
INTEGERFN PARAM DES(INTEGER TYPE)
!***********************************************************************
!* SET UP BNDED L=1 DESRIPTOR FOR PASSING VARIABLE BY REFERENCE *
!* ONLY THE TOP HALF IS SET UP *
!***********************************************************************
INTEGER K,DES,PREC
 PREC=SIZECODE(TYPE)
 K=DESADS(PREC)
 RESULT =K UNLESS K=0
 DES=PREC<<27!1
 STORE CONST (K,4,DES,0)
 DESADS(PREC)=K
 RESULT =K
END 
INTEGERFN SPECIAL CONSTS(INTEGER WHICH)
!***********************************************************************
!* PUTS CERTAIN SPECIAL CONSTANTS INTO THE CONSTANT TABLE ON *
!* DEMAND AND REMEMBERS THEIR POSN TO AVOID SEARCHONG *
!***********************************************************************
CONSTINTEGERARRAY SCS(0:5) = X'40800000',0,
 X'41100000',0,
 X'E5000000',X'E5000001';
INTEGER K
 K=DESADS(WHICH+16)
 RESULT =K UNLESS K=0
 STORE CONST(K,8,SCS(2*WHICH),SCS(2*WHICH+1))
 DESADS(WHICH+16)=K
 RESULT =K
END 
ROUTINE STORE CONST(INTEGERNAME D, INTEGER L, C1, C2)
!***********************************************************************
!* PUT THE CONSTANT VAL OF LENGTH 'L' INTO THE CONSTANT TABLE *
!* A CHECK IS MADE TO SEE IF THE CONSTANT HAS ALREADY *
!* BEEN INSERTED IN WHICH CASE THE OLD COPY IS REUSED *
!***********************************************************************
INTEGER I, J, K, LP
 LP=L//4
 IF PARMOPT#0 THEN ->SKIP
 K=CONST BTM; ! AFTER STRINGS IN CTABLE
 IF L=4 THEN START 
 IF INCLUDE HANDCODE=NO THEN START 
 WHILE K<CONST PTR CYCLE 
 IF CTABLE(K)=C1 AND CONSTHOLE#K C 
 THEN D=4*K!X'80000000' AND RETURN 
 K=K+1
 REPEAT 
 FINISH ELSE START 
 *LD_CTABLE
 *LB_K
 *SBB_1
 *LSS_C1
AGN1:
 *ADB_1
 *CPB_CONSTPTR
 *JCC_10,<SKIP>
 *ICP_(DR +B )
 *JCC_7,<AGN1>
 *CPB_CONSTHOLE
 *JCC_8,<AGN1>
 *LSS_B 
 *IMY_4
 *OR_X'80000000'
 *ST_(D)
 *EXIT_-64
 FINISH 
 FINISH ELSE START 
 J=CONSTPTR-LP
 IF INCLUDE HANDCODE=NO THEN START 
 WHILE K<=J CYCLE 
 IF CTABLE(K)=C1 AND CTABLE(K+1)=C2 AND C 
 (CONSTHOLE<K OR CONSTHOLE>=K+LP) START 
 D=4*K!X'80000000'
 RETURN 
 FINISH 
 K=K+2
 REPEAT 
 FINISH ELSE START 
 *LD_CTABLE
 *LB_K
AGN2A:
 *LSS_C1
AGN2:
 *CPB_J
 *JCC_2,<SKIP>
 *ICP_(DR +B )
 *JCC_8,<ON2>
 *ADB_2
 *J_<AGN2>
ON2:
 *STB_K
 *ADB_1
 *LSS_(DR +B )
 *ICP_C2
 *JCC_8,<ON2A>
BACK2:
 *ADB_1
 *J_<AGN2A>
ON2A:
 *LSS_K
 *ICP_CONSTHOLE
 *JCC_8,<BACK2>
 *CPB_CONSTHOLE
 *JCC_8,<BACK2>
 *IMY_4
 *OR_X'80000000'
 *ST_(D)
 *EXIT_-64
 FINISH 
 FINISH 
SKIP:
 IF L=4 AND CONSTHOLE#0 START 
 CTABLE(CONSTHOLE)=C1
 D=4*CONSTHOLE!X'80000000'
 CONSTHOLE=0
 RETURN 
 FINISH 
 IF L>4 AND CONST PTR&1#0 C 
 THEN CONSTHOLE=CONST PTR AND CONSTPTR=CONST PTR+1
 D=4*CONST PTR!X'80000000'
 CTABLE(CONSTPTR)=C1
 CTABLE(CONSTPTR+1)=C2
 CONST PTR=CONST PTR+LP
 IF CONST PTR>CONST LIMIT THEN FAULT(107,0)
END 
ROUTINE GET ENV(INTEGERNAME HEAD)
!***********************************************************************
!* SAVE A COPY OF THE REGISTER STATE FOR FUTURE REFERENCE *
!***********************************************************************
INTEGER I,J
 CYCLE J=0, 1, 4; I=GRMAP(J)
 PUSH(HEAD, GRINF(I), GRAT(I), I<<8!GRUSE(I)) C 
 IF GRUSE(I)>1
 REPEAT 
END 
ROUTINE RESTORE(INTEGER HEAD)
!***********************************************************************
!* RESET THE REGISTERS TO ENVIRONMENT IN LIST HEADED BY 'HEAD' *
!***********************************************************************
INTEGER I, J, R, USE, INF, AT
 CYCLE J=0, 1, 4; I=GRMAP(J)
 GRUSE(I)=0; GRINF(I)=0
 REPEAT 
 WHILE HEAD#0 CYCLE 
 POP(HEAD, INF, AT, I)
 R=I>>8; USE=I&255
 GRUSE(R)=USE; GRINF(R)=INF
 GRAT(R)=AT
 REPEAT 
END 
 ROUTINE RELOCATE(INTEGER GLARAD,VALUE,AREA)
!***********************************************************************
!* PLANTS A WORD IN THE GLA (IF GLARAD<0) AND ARRANGES TO *
!* RELOCATE IT RELATIVE TO AN AREA(CODE=1,GLA=2,CST=4,GST=5 *
!* IF THE RELOCATION IS RELATIVE TO SYMBOL TABLES THE WORD *
!* CAN NOT BE RELOCATED TILL SIZE OF THE CODE(OR GLA) IS KNOWN *
!***********************************************************************
 IF GLARAD<0 THEN PGLA(4,4,ADDR(VALUE)) AND GLARAD=GLACA-4
 LPUT(19,2,GLARAD,AREA)
 END 
 ROUTINE GXREF(STRING (31) NAME,INTEGER MODE,XTRA,AT)
!***********************************************************************
!* ASK LPUT TO ARRANGE FOR A DOUBLE WORD AT 'AT' IN THE GLA *
!* TO CONTAIN A DESCRIPTOR FOR NAME 'NAME'. *
!* MODE=0 STATIC CODE XREF *
!* MODE=1 DYNAMIC CODE XREF *
!* MODE=2 DATA XREF XTRA=MINIMIUM LENGTH *
!***********************************************************************
INTEGER LPUTNO
 IF MODE=2 THEN LPUTNO=15 ELSE LPUTNO=MODE+12
 LPUT(LPUTNO,XTRA,AT,ADDR(NAME))
 END 
ROUTINE CXREF(STRING (255) NAME,INTEGER MODE,XTRA,INTEGERNAME AT)
!***********************************************************************
!* CREATE A ZEROED AREA IN THE GLA AND CALL GXREF TO GET *
!* IT FILLED AT LOAD TIME WITH INFORMATION ON AN EXTERNAL OBJECT *
!* PARAMETERS ARE AS FOR GXREF. *
!***********************************************************************
INTEGER Z1,Z2
 Z1=0; Z2=0
 PGLA(4,8,ADDR(Z1)); ! 2 ZERO WORDS
 AT=GLACA-8
 GXREF(NAME,MODE,XTRA,AT)
 END 
ROUTINE CODEDES(INTEGERNAME AT)
!***********************************************************************
!* PUT A CODE DESCRIPTOR INTO THE PLT FOR USE BY DEFINE EP *
!***********************************************************************
INTEGER DESC1,DESC2
 DESC1=X'E1000000'; DESC2=0
 IF CDCOUNT=0 THEN FIXED GLA(0)=DESC1 AND AT=0 C 
 ELSE PGLA(4,8,ADDR(DESC1)) AND AT=GLACA-8
 CDCOUNT=CDCOUNT+1
END 
ROUTINE DEFINE EP(STRING (255)NAME, INTEGER ADR,AT,MAIN)
!***********************************************************************
!* AN EP CONSISTS OF A CODE DESCRIPTOR IN THE GLA(PLT) OF *
!* FILE CONTAINING THE EP. LPUT IS TOLD ABOUT THIS AND THE LOADER*
!* ARRANGES TO PUT A DESCRIPTOR-DESCRIPTOR TO THE CODE-DESC *
!* IN THE GLA OF ANY FILE REFERENCES THIS EP. THIS FIRST WORD *
!* OF ICLS PLT IS THE MAIN EP AND WE MIMIC THIS AS FAR AS POSS *
!***********************************************************************
 IF AT=0 THEN FIXED GLA(1)=ADR ELSE PLUG(2,AT+4,ADR)
 RELOCATE(AT+4,ADR,1)
 LPUT(11,MAIN<<31!2,AT,ADDR(NAME)) IF NAME#''
END 
ROUTINE PROLOGUE
!***********************************************************************
!* GENERATES THE SUBROUTINE THAT ALWAYS ARE REQUIRED ONTO THE *
!* FRONT OF THE OBJECT PROGRAM WHERE THEY ARE DIRECTLY ADDRESABLE*
!***********************************************************************
INTEGERFNSPEC STRINGIN(INTEGER POS)
ROUTINESPEC ERR EXIT(INTEGER A, B, C)
INTEGER I, J, K, L, STCA
 J=X'C2C2C2C2'
 LPUT(4,4,0,ADDR(J))
 CYCLE I=0, 1, 31
 DESADS(I)=0; PLABS(I)=0; PLINK(I)=0
 REPEAT 
 SSTL=4
!
! NEXT GENERATE THE FIXED-FLOAT CONSTANTS THAT MAY BE NEEDED
!
 PLABS(1)=CA
 CYCLE I=0, 1, 1
 PCONST(UNASSPAT)
 REPEAT 
!
! GENERATE THE RUN TIME ERROR ROUTINE :-
! MDIAGS FOR NR IS %ROUTINE MDIAGS(%INT PC,LNB,ERROR,XTRA)
! PC IS A DUMMY (SEG FIELD ONLY USED) EXCEPT AFTER CONTINGENCY
! ON ENTRY TO THIS SUBROUTINE ERROR IS IN ACC. XTRA HAS BEEN STACKED
! ENTRY HAS BEEN BY JLK SO RETURN ADDRESS ALSO STACKED
!
!RTF LB TOS RETURN ADDRESS TO B
! SLB TOS XTRA TO B,RETURN ADDR TO TOS
! PRCL 4 START AN EXTERNAL CALL
! JLK +1 STACK DUMMY PC
! STLN TOS LNB AS SECOND PARAMETER
! ST TOS ERROR NO AS THIRD PARAM
! STB TOS XTRA AS FOURTH PARAMETER
! LXN (LNB+4) POINTER TO GLA
! RALN 9 TO STORED LNB
! CALL ((XNB+10)) VIA XREF=DESCRIPTOR-DESCRIPTOR
! J TOS BACK AFTER A MONITOR
!
 PLABS(2)=CA
! PF1(LB,0,TOS,0)
! PF1(SLB,0,TOS,0)
! PSF1(PRCL,0,4)
! PSF1(JLK,0,1)
! PF1(STLN,0,TOS,0)
! PF1(ST,0,TOS,0)
! PF1(STB,0,TOS,0)
! PSF1(LXN,1,16)
! PSF1(RALN,0,9)
! PF1(CALL,2,XNB,40)
! PF1(JUNC,0,TOS,0)
 PCLOD(0,5)
!
! SUBROUTINE TO ADVANCE STACK FRONT BY B WORDS AND FILL WITH UNASSIGNED
!
! JAT 12,*+13 B IS ZERO
! LSS TOS
! STSF TOS
! LDTB STRING DECRIPTOR SET UP DESCRIPTOR FOR MVL
! LDA TOS
! ASF B ADVANCE BY B WORDS
! MYB 4 CHANGE B TO BYTES
! LDB B AND MOVE TO BOUND FIELD
! MVL L=DR AND FILL WITH X80S
! ST TOS
! J TOS RETURN
!
 IF PARMCHK=1 THEN START ; ! ONLY REQUIRED WITH CHKING
 CNOP(0,4); I=CA
 PCONST(X'18000000')
 PLABS(3)=CA
 PF1(LDTB,0,PC,I)
! PF3(JAT,12,0,11)
! PF1(LSS,0,TOS,0)
! PF1(STSF,0,TOS,0)
! PF1(LDA,0,TOS,0)
! PF1(ASF,0,BREG,0)
! PSF1(MYB,0,4)
! PF1(LDB,0,BREG,0)
! PF2(MVL,1,1,0,0,UNASSPAT&255)
! PF1(ST,0,TOS,0)
! PF1(JUNC,0,TOS,0)
 PCLOD(8,13)
 FINISH 
!
! SUBROUTINE TO RESET STACK FRONT TO VALUE IN ACC. LINK IS ON TOS
! B MUST NOT BE ALTERED MAY HAVE SWITCH VALUE IN IT
!
!RESET STSF TOS IN BYTES
! ISB TOS ADJUSTMENT IN BYTES
! ISH -2 IN WORDS
! IAD 1 ALLOW FOR DESTACKING RETURN ADDR
! SLSS TOS
! ASF TOS
! ST TOS
! J TOS
!
 PLABS(4)=CA
! PF1(STSF,0,TOS,0)
! PF1(ISB,0,TOS,0)
! PSF1(ISH,0,-2)
! PSF1(IAD,0,1)
! PF1(SLSS,0,TOS,0)
! PF1(ASF,0,TOS,0)
! PF1(ST,0,TOS,0)
! PF1(JUNC,0,TOS,0)
 PCLOD(15,18)
!
! SOME ERROR ROUTINES
!
 ERR EXIT(5, X'801', 0) IF PARMCHK#0;! UNASSIGNED VARIABLE
! ERR EXIT(6, X'602', 0); ! ARRAY BOUND EXCEEDED
 ERR EXIT(7, X'505', 0) IF PARMOPT#0;! ILLEGEAL EXPONENTIATION
 ERR EXIT(8, X'201', 0) IF PARMOPT#0;! EXCESS BLOCKS
 ERR EXIT(9, 22, 0); ! LHS NOT DESTIN
 ERR EXIT(10,36,0) IF PARMOPT#0; ! WRONG PARAM TO EXTERNAL
!
! PUT THE STRINGS ONTO THE FRONT OF CONSTANT AREA
!
 CTABLE(0)=X'18000100'
 CTABLE(1)=4
 STCA=8; L=ADDR(CTABLE(0))
 CONST PTR=2; ! IN CASE NO STRINGS
 WHILE STRLINK#0 CYCLE 
 I=STRLINK; STRLINK=A(I)
 A(I)=STRINGIN(I+1); ! CHANGE LINK TO STRING ADDR
 REPEAT 
 STRLINK=X'80000000'
 CONST BTM=CONST PTR
 CTABLE(CONST PTR)=M'ADIA'
 CONST PTR=CONST PTR+1
 CYCLE I=0,1,31
 IF PLINK(I)#0 THEN CLEAR LIST(PLINK(I))
 REPEAT 
 GXREF(MDEP,0,2,40)
 GXREF(AUXSTEP,2,X'02000008',52)
 AUXST=48
 CYCLE I=0,1,NNAMES
 TAGS(I)=0
 REPEAT 
 CYCLE I=0,1,MAXLEVELS
 RAL(I)=0
 REPEAT 
 J=SNUM; SNUM=0; LEVEL=0
 CYCLE I=1,1,J
 A(R)=13; A(R+1)=SNNNO(I)
 CSS(R); ! DECLARE THE SPECIAL NAME
 REPEAT 
 LEVEL=1
 RETURN 
INTEGERFN STRINGIN(INTEGER POS)
!***********************************************************************
!* PUT A STRING INTO THE CONSTANT AREA CHECKING FOR DUPLICATES *
!***********************************************************************
INTEGER J,K,IND,HD,AD,SYM
RECORDNAME CELL(LISTF)
 K=A(POS); ! STRING LENGTH
 IF K=0 THEN RESULT =0
 IND=K&31; HD=PLINK(IND)
 WHILE HD#0 CYCLE 
 EXIT IF K>255; ! FOR LONG EBCDIC STRINGS
 CELL==ASLIST(HD)
 IF CELL_S1=K AND STRING(L+CELL_S2)=STRING(ADDR(A(POS))) C 
 THEN RESULT =CELL_S2-4
 HD=CELL_LINK
 REPEAT 
 HD=STCA; AD=ADDR(A(POS))+3
 BYTEINTEGER(L+STCA)<-K; STCA=STCA+1
 CYCLE J=AD+1,1,AD+K
 SYM=BYTE INTEGER(J)&127
 IF EBCDIC#0 THEN SYM=ITOETAB(SYM)
 BYTE INTEGER(L+STCA)=SYM
 STCA=STCA+1
 REPEAT 
 CONST PTR=((STCA+7)&(-8))>>2
 PUSH(PLINK(IND),K,HD,0)
 RESULT =HD-4
END 
ROUTINE ERR EXIT(INTEGER LAB, ERRNO, MODE)
!***********************************************************************
!* MODE=0 FOR DUMMY(ZERO) XTRA - MODE=1 XTRA IN ACC *
!***********************************************************************
 PLABS(LAB)=CA
 IF MODE=0 THEN PLANT(X'6200');! LSS 0
 PSF1(SLSS,0,ERRNO)
 PSF1(JLK,0,(PLABS(2)-CA)//2)
END 
END 
ROUTINE EPILOGUE
!***********************************************************************
!* PLANT ANY SUBROUINES THAT HAVE BEEN REQUIRED DURING *
!* THE CODE GENERATION PHASE *
!***********************************************************************
ROUTINESPEC FILL(INTEGER LAB)
!
! ARRAY BY VALUE SUBROUTINE
! ***** ** ***** **********
! ENTERED BY A CALL WITH 1 PARAMETER (THE HEADER ) STACKED
! B HAS THE SIZE CODE FOR COPIED ARRAY
! EXITS WITH NEW HEADER IN ACC
!
! LXN (LNB+0) OLD VALUE OF LNB
! LXN (XNB+4) XNB TO PLT
! LSD (LND+5) COPY ORIGINAL ARRAY DESCRIPTOR
! ST %TOS TO (LNB+9) AND ASF 2
! LD ((XNB+AUXST))
! LSS @DR AUX STACK STACKPOINTER
! ST (LNB+6) CORRECTED HEADER
! LSS (LNB+9) GET SIZE CODE FOR ORIGINAL
! ISH -27
! AND 7
! ICP B COMPARE WITH REQUIRED
! JCC 2,RASI FIXING REQUIRED
! JCC 4,IASR FLOATING REQD
! AND 3 SIZE CODE NOW 1 OR 2
! IMY 4 BYTE PER ELEMENT IN AC
! SLSS (LNB+5) GET NO OF ELEMENT
! AND X1FFFF REMOVE TYPE BITS
! IMY TOS SIZE OF ARRAY IN BYTE
! ST B
! IAD (LNB+6) UPDATE AUX STACK PTR
! ST @DR ROUNDED VALUE STORED
! ICP @DR+2 CHECK TOP OF AUXSTACK
! JCC 2,XBLKS
! LDTB BYTE DESCRIPTOR
! LDB B
! LDA (LNB+10) BYTE DESCPTR TO OLD ARRAY
! CYD 0 AS SOURCE STRING
! LDA (LNB+6) DITTO AS DESTN STRING
! MV L=DR MAKE THE COPY
! LSQ (LNB+5) NEW HEADER
! EXIT
!
!IASR LSS 1
! ISH 27
! IAD (LNB+9) CONVERT 32 TO 64 DECSRPT
! ST (LNB+5) AND PUT INTO HEAD
! AND X'1FFFF' GET NO OF ELEMENTS
! ST B
! IMY 8 SPACE REQUIRED
! IAD (LNB+6) UPDATE AUX ST PNTR
! ST @DR
! ICP @DR+2 AND CHECK FOR O'FLOW
! JCC 2,XBLKS
!LOOP SBB 1 STEP THRO ELEMENTS
! LSS ((LNB+9)),B GET OLD INTEGER ELEMENT
! FLT 0 FLOAT IT
! ST ((LNB+5)),B AND STORE IN NEW COPY OF ARRAY
! JAF 12,LOOP
! LSQ (LNB+5) PICK UP NEW HEAD
! EXIT
!
!RASI LSS 1
! ISH 27
! IRSB (LNB+9) CONVERT 64 T0 32 BIT DECRPTR
! ST (LNB+5) AND PUT IN NEW HEADER
! AND X'1FFFF' GET NO OF ELEMENTS
! ST B
! IMY 4
! IAD (LNB+6) UPDATE AUX ST PNTR
! ST @DR
! ICP @DR+2 AND CHECK FOR O'FLOW
! JCC 2,XBLKS
!LOOP SBB 1 STEP THRO ELEMENTS
! LSD ((LNB+9)),B GET OLD REAL ELEMENT
! RAD D'0.5' AND FIX IT
! RSC 55
! RSC -55
! STB TOS
! FIX B
! MYB 4
! ISH B
! MPSR 17
! LB TOS
! ST ((LNB+5)),B AND STORE FIXED INTEGER ELEMENT
! JAF 12,LOOP
! LSQ (LNB+5)
! EXIT
!XBLKS J ERROR RT 8
!
 IF PLINK(13)=0 THEN ->P14
 FILL(13)
! PSF1(LXN,1,0)
! PF1(LXN,0,XNB,16)
! PSF1(LSD,1,20)
! PF1(ST,0,TOS,0)
! PF1(LD,2,XNB,AUXST); ! NB CHANGES WITH AUXST****
! PF1(LSS,2,7,0)
! PSF1(ST,1,24)
! PSF1(LSS,1,36)
! PSF1(ISH,0,-27)
! PSF1(AND,0,7)
! PF1(ICP,0,BREG,0)
! PF3(JCC,2,0,50)
! PF3(JCC,4,0,24)
! PSF1(AND,0,3)
! PSF1(IMY,0,4)
! PSF1(SLSS,1,20)
! PF1(AND,0,0,X'1FFFF')
! PF1(IMY,0,TOS,0)
! PF1(ST,0,BREG,0)
! PSF1(IAD,1,24)
! PF1(ST,2,7,0)
! PF1(ICP,1,0,2)
! PF3(JCC,2,0,X'44')
 PCLOD(42,56)
 PF1(LDTB,0,PC,PARAM DES(5))
! PF1(LDB,0,BREG,0)
! PF1(LDA,0,TOS,0)
! PSF1(CYD,0,0)
! PSF1(LDA,1,24)
! PF2(MV,1,0,0,0,0)
! PSF1(LSQ,1,20)
! PSF1(EXIT,0,0)
! PSF1(LSS,0,1)
! PSF1(ISH,0,27)
! PSF1(IAD,1,36)
! PSF1(ST,1,20)
! PF1(AND,0,0,X'1FFFF')
! PF1(ST,0,BREG,0)
! PSF1(IMY,0,8)
! PSF1(IAD,1,24)
! PF1(ST,2,7,0)
! PF1(ICP,1,0,2)
! PF3(JCC,2,0,X'2D')
! PSF1(SBB,0,1)
! PF1(LSS,3,LNB,36)
!! PSF1(FLT,0,0)
! PF1(ST,3,LNB,20)
! PF3(JAF,12,0,-6)
! PSF1(LSQ,1,20)
! PSF1(EXIT,0,0)
! PSF1(LSS,0,1)
! PSF1(ISH,0,27)
! PSF1(IRSB,1,36)
! PSF1(ST,1,20)
! PF1(AND,0,0,X'1FFFF')
! PF1(ST,0,BREG,0)
! PSF1(IMY,0,4)
! PSF1(IAD,1,24)
! PF1(ST,2,7,0)
! PF1(ICP,1,0,2)
! PF3(JCC,2,0,X'15')
! PSF1(SBB,0,1)
! PF1(LSD,3,LNB,36)
 PCLOD(57,80)
 PF1(RAD,0,PC,SPECIAL CONSTS(0));! 0.5
! PSF1(RSC,0,55)
! PSF1(RSC,0,-55)
! PF1(STB,0,TOS,0)
! PF1(FIX,0,BREG,0)
! PSF1(MYB,0,4)
! PF1(ISH,0,BREG,0)
! PSF1(MPSR,0,17)
! PF1(LB,0,TOS,0)
! PF1(ST,3,LNB,20)
! PF3(JAF,12,0,-15)
! PSF1(LSQ,1,20)
! PSF1(EXIT,0,0)
 PCLOD(82,88)
 PF1(JUNC,0,0,(PLABS(8)-CA)//2)
P14:
!
! EVALUATE X**Y
! ******** ****
! Y IS IN ACC X IS STACKED BELOW THE LINK(UNAVOIDABLE)
! FAULT(21) IS GIVEN IF X<0 OR (X=0 AND Y<=0)
! REPEATED MULTIPLICATION IS USED IF Y>0 AND FRACPT(Y)=0
! OTHERWISE RESULT=EXP(Y*LOG(Y))
!
! LB TOS SWOP RETURN ADDRESS & X
! LD TOS X TO DR
! STB TOS
! STD TOS
! SLSD TOS X TO ACC Y TO TOS
! JAT 2,EXPERR ERROR IF X<0
! JAF 0,TRYMULT JUMP X#0
! SLSD TOS STACK X & GET Y
! JAF 1.EXPERR Y<=0
! LSD TOS X (=0) =RESULT TO ACC
! J TOS RETURN
!TRYMULT X IS IN ACC & Y STACKED
! SLSD TOS Y TO ACC AND X STACKED
! ST TOS Y STACKED
! JAT 2,NONINT Y IS NEGATIVE
! RSC 55
! RSC -55
! FIX B FIX PINCHED FROM ICL ALGOL
! MYB 4
! CPB -64
! JCC 10,*+3
! LB -64
! ISH B
! STUH B ACC TO 1 WORD
! JCC 7,NONINT JUMP IF TRUNCATION
! ASF -2 LOSE Y OF STACK
! ST B INTEGER VERSION OF Y TO B
! LSS 1
! FLT 0
! JAF 12,MUL JUMP IF B#0
! ASF -2 LOSE X OFF STACK
! J TOS X**0 =1
!AGN STD TOS STACK ANOTHER COPY OF X
!MUL RMY TOS
! DEBJ AGN REPEATED MULTIPLICATION
! J TOS
!NONINT Y IS STACKED OVER X
! LSD TOS
! SLSD TOS
! PRCL 4
! ST TOS
! LXN (LNB+4)
! RALN 7
! CALL ((XNB+LOGEPDISP)
! RMY TOS
! PRCL 4
! ST TOS
! LXN (LNB+4) TO PLT
! RALN 7
! CALL ((XNB+EXPEPDISP)) CALL EXP
! J TOS
!EXPERR J ERROR RT NO 7
!
 IF PLINK(14)=0 THEN ->P15
 FILL(14)
 IF LOGEPDISP=0 THEN CXREF('S#ILOG',PARMDYNAMIC,2,LOGEPDISP)
 IF EXPEPDISP=0 THEN CXREF('S#IEXP',PARMDYNAMIC,2,EXPEPDISP)
! PF1(LB,0,TOS,0)
! PF1(LD,0,TOS,0)
! PF1(STB,0,TOS,0)
! PF1(STD,0,TOS,0)
! PF1(SLSD,0,TOS,0)
! PF3(JAT,2,0,X'37')
! PF3(JAF,0,0,7)
! PF1(SLSD,0,TOS,0)
! PF3(JAF,1,0,X'32')
! PF1(LSD,0,TOS,0)
! PF1(JUNC,0,TOS,0)
! PF1(SLSD,0,TOS,0)
! PF1(ST,0,TOS,0)
! PF3(JAT,2,0,26)
! PSF1(RSC,0,55)
! PSF1(RSC,0,-55)
! PF1(FIX,0,BREG,0)
! PSF1(MYB,0,4)
! PSF1(CPB,0,-64)
! PF3(JCC,10,0,3)
! PSF1(LB,0,-64)
! PF1(ISH,0,BREG,0)
! PF1(STUH,0,BREG,0)
! PF3(JCC,7,0,14)
! PSF1(ASF,0,-2)
! PF1(ST,0,BREG,0)
! PSF1(LSS,0,1)
! PSF1(FLT,0,0)
! PF3(JAF,12,0,5)
! PSF1(ASF,0,-2)
! PF1(JUNC,0,TOS,0)
! PF1(STD,0,TOS,0)
! PF1(RMY,0,TOS,0)
! PSF1(DEBJ,0,-2)
! PF1(JUNC,0,TOS,0)
! PF1(LSD,0,TOS,0)
! PF1(SLSD,0,TOS,0)
! PSF1(PRCL,0,4)
! PF1(ST,0,TOS,0)
! PSF1(LXN,1,16)
! PSF1(RALN,0,7)
 PCLOD(90,113)
 PF1(CALL,2,XNB,LOGEPDISP)
! PF1(RMY,0,TOS,0)
! PSF1(PRCL,0,4)
! PF1(ST,0,TOS,0)
! PSF1(LXN,1,16)
! PSF1(RALN,0,7)
 PCLOD(115,117)
 PF1(CALL,2,XNB,EXPEPDISP)
 PF1(JUNC,0,TOS,0)
 PF1(JUNC,0,0,(PLABS(7)-CA)//2)
P15:
 IF PLINK(15)=0 THEN ->P16
 FILL(15)
!
! CONTINGENCY ENTRY - LNB RESTORE FOR MAIN PROGRAM. ACC HAS WORD DECP
! TO 18 WORD AREA OF FAILURE & IMAGE STORE:-
! WORD0 = FAILURE?, WORD1=XTRA?,WORD2=LNB,WORD4=PC
! THIS ROUTINE TRANSCRIBES THESE INTO A CALL ON MDIAGS
!
! ST TOS
! LD TOS DESCRIPTOR TO DR
! PRCL 4 START RT CALL
! LSS (DR+4) PC FIRST PARAM
! SLSS (DR+2) LNB SECOND PARAM
! SLSS 10 INTERRUPT OF CLASS
! SLSS (DR) XTRA IS CLASS NO
! ST TOS
! LXN (LNB+4) TO PLT(GLA)
! RALN 9
! CALL ((XNB+10)) TO MDIAGS - DOES NOT RETURN
!
! PF1(ST,0,TOS,0)
! PF1(LD,0,TOS,0)
! PSF1(PRCL,0,4)
! PF1(LSS,1,0,4)
! PF1(SLSS,1,0,2)
! PSF1(SLSS,0,10)
! PF1(SLSS,2,7,0)
! PF1(ST,0,TOS,0)
! PSF1(LXN,1,16)
! PSF1(RALN,0,9)
! PF1(CALL,2,XNB,40)
 PCLOD(20,26)
P16:
 IF PLINK(16)=0 THEN ->P17
 FILL(16)
!
! THE STOP SEQUENCE
! CALL %SYSTEMROUTINE STOP(NO PARAMETERS)
!
!STOP1 PRCL 4
! LXN (LNB+4)
! RALN 5
! CALL ((XNB+STOPEPDISP)) ! **PLEASE DONT COME BACK**
!
 CXREF('S#STOP',PARMDYNAMIC,2,J)
 PCONST(X'18047E84'); ! PRCL 4-- LXN (LNB+4)
 PLANT(X'6C05'); ! RALN 5
 PF1(CALL,2,XNB,J)
P17:
! ROUTINE PARAMETER SUBROUTINE
! B HAS FOURTH PARAMETER (ENV) WORD
! ACC (32BITS) HAS DESCRIPION WORD M'AE'&M'IMP' INDICATE THE OLD
! COMPILERS WITH ENV IN XNB
! ALL OTHER NON ZERO ENVIRONMENTS ARE STACKED
!
! LXN B XNB IS ENV OR IMMATERIAL
! JAF 12,*+6 ZERO B = NO ENV
!OLDAE J TOS
! ICP M'AE'
! JCC 8,OLDAE OLD ALGOL(E)
! ICP M'IMP'
! JCC 8,OLDAE OLD IMP AS OLD AE
! SLB TOS STACK PARM RETURN ADDR TO B
! J B
 IF PLINK(17)=0 THEN ->P18
 CNOP(0,4)
 PCONST(M'IMP')
 FILL(17)
 PF1(LXN,0,BREG,0)
 PF3(JAF,12,0,3)
 PF1(JUNC,0,TOS,0)
 PF1(ICP,0,0,M'AE')
 PF3(JCC,8,0,-3)
 PF1(ICP,0,PC,CA-20)
 PF3(JCC,8,0,-4)
 PF1(SLB,0,TOS,0)
 PF1(JUNC,0,BREG,0)
P18:
 RETURN 
ROUTINE FILL(INTEGER LAB)
!***********************************************************************
!* FILL JUMPS TO THIS LAB WITH JUMP TO CURRENT ADDRESS *
!***********************************************************************
INTEGER AT,INSTRN,SPARE
 WHILE PLINK(LAB)#0 CYCLE 
 POP(PLINK(LAB),AT,INSTRN,SPARE)
 INSTRN=INSTRN!(CA-AT)>>1
 PLUG(1,AT,INSTRN)
 REPEAT 
 PLABS(LAB)=CA
END 
END 
ROUTINE DUMP CONSTS
!***********************************************************************
!* OUTPUT THE CONSTANT TABLE AND MAKE ANY RELEVANT RELOCATIONS *
!***********************************************************************
ROUTINESPEC DOIT(INTEGER VAL)
INTEGER I,J,K,DISP
 LPUT(1,CONSTPTR*4,CA,ADDR(CTABLE(0))) IF CONSTPTR#0
 IF ALLOW CODELIST=YES AND DCOMP#0 START 
 IF VMEB=YES THEN FAULTMK(4); ! START OF CODE ETC
 PRINTSTRING("
CONSTANT TABLE")
 I=0
 CYCLE 
 NEWLINE
 PRHEX(CA+4*I,5)
 CYCLE J=0,1,7
 SPACES(2)
 PRHEX(CTABLE(I+J),8)
 REPEAT 
 SPACE
 CYCLE J=0,1,31
 K=BYTEINTEGER(ADDR(CTABLE(I))+J)
 IF K<31 OR K>95 THEN K=32
 PRINT SYMBOL(K)
 REPEAT 
 I=I+8
 EXIT IF I>=CONSTPTR
 REPEAT 
 NEWLINE
 IF VMEB=YES THEN FAULTMK(1); ! BACK TO NORMAL
 FINISH 
!
 DISP=CA//2; ! RELOCATION FACTOR
 WHILE CREFHEAD#0 CYCLE 
 POP(CREFHEAD,I,J,K)
 DOIT(I)
 IF J#0 THEN DOIT(J)
 IF K#0 THEN DOIT(K)
 REPEAT 
 CA=CA+4*((CONSTPTR+1)&(-2))
 DISP=2*DISP; ! NOW UPDATE DESRPTR TO CONST
 ! WHICH ARE IN GLA
 WHILE GLARELOCS#0 CYCLE 
 POP(GLARELOCS,I,J,K)
 J=J+DISP
 LPUT(2,4,I,ADDR(J))
 REPEAT 
 RETURN 
ROUTINE DOIT(INTEGER VAL)
!***********************************************************************
!* IF VAL +VE THEN VAL IS CODE ADDRESS FOR LPUT(18) UPDATE *
!* IF VAL -VE IT IS GLAWRDADDRR<<16!CTABLE WRD ADDR *
!* THE GLA WORD IS TO RELOCATED BY HEAD OF CODE(ALREADY DONE) *
!* HOWEVER THE GLAWORD NEEDS UPDATING FROM REL CTABLE TO REL CODE *
!***********************************************************************
INTEGER I,J
 IF VAL>0 THEN LPUT(18,0,VAL,DISP) ELSE START 
 I=(VAL>>16&X'7FFF')<<2; ! GLA BYTE ADDRESS
 J=4*(VAL&X'FFFF')+CA; ! CTABLE ENTRY REL HD OF CODE
 PLUG(2,I,J); ! UPDATE THE GLA WORD
 FINISH 
END 
END 
ROUTINE CSS(INTEGER P)
ROUTINESPEC MERGE INFO
ROUTINESPEC REDUCE ENV(INTEGERNAME HEAD)
ROUTINESPEC ENTER JUMP(INTEGER MASK,STAD,FLAG)
ROUTINESPEC ENTER LAB(INTEGER M,FLAG,LEVEL)
ROUTINESPEC CEND(INTEGER KKK)
ROUTINESPEC RESET AUX STACK
ROUTINESPEC SAVE AUX STACK(INTEGER ARRS)
ROUTINESPEC CBPAIR(INTEGERNAME LB,UB)
ROUTINESPEC CCOND
ROUTINESPEC SET LINE
ROUTINESPEC C FORSTMNT
ROUTINESPEC CSTMNT
ROUTINESPEC CUI
ROUTINESPEC GOTOLAB(INTEGER MODE)
ROUTINESPEC CDE(INTEGER MODE)
ROUTINESPEC CSDE(INTEGER MODE)
ROUTINESPEC CCMPNDSTMNT
ROUTINESPEC CBLK(INTEGER BLKTYPE)
ROUTINESPEC ETORP(INTEGERNAME A,B,INTEGER C)
ROUTINESPEC TORP(INTEGERNAME HEAD,NOPS,INTEGER MODE)
ROUTINESPEC SET USE(INTEGER R,U,I)
ROUTINESPEC CSEXP(INTEGER REG,MODE,NME)
ROUTINESPEC SAVE IRS
ROUTINESPEC BOOT OUT(INTEGER MODE)
ROUTINESPEC EXPOP(INTEGER A,B,C,D)
ROUTINESPEC TEST APP(INTEGERNAME NUM)
ROUTINESPEC SKIP EXP(INTEGER MODE)
ROUTINESPEC SKIP SEXP(INTEGER MODE)
ROUTINESPEC SKIP APP
INTEGERFNSPEC DOPE VECTOR(INTEGER A,B,INTEGERNAME C,D)
ROUTINESPEC MAKE DECS(INTEGER P,K)
ROUTINESPEC DECLARE OWNS
ROUTINESPEC DECLARE ARRAYS
ROUTINESPEC DECLARE SCALARS
ROUTINESPEC DECLARE LAB
ROUTINESPEC DECLARE PROC
ROUTINESPEC DECLARE SWITCH
ROUTINESPEC CLABEL
ROUTINESPEC COLABEL
ROUTINESPEC GET WSP(INTEGERNAME PLACE,INTEGER SIZE)
ROUTINESPEC RETURN WSP(INTEGER PLACE,SIZE)
ROUTINESPEC GTHUNKS(INTEGER A,B)
INTEGERFNSPEC CHECK FPROCS(INTEGER A,B)
ROUTINESPEC CRCALL(INTEGER A)
ROUTINESPEC CALL THUNKS(INTEGER A,REG,B,C)
ROUTINESPEC FETCH STRING(INTEGER REG)
ROUTINESPEC CNAME(INTEGER Z,REG)
ROUTINESPEC CANAME(INTEGER Z,BS,DP)
ROUTINESPEC CSNAME(INTEGER Z,REG)
ROUTINESPEC COPY TAG(INTEGER KK)
ROUTINESPEC REDUCE TAG
ROUTINESPEC REPLACE TAG (INTEGER KK)
ROUTINESPEC RT JUMP(INTEGER CODE,INTEGERNAME RT)
ROUTINESPEC STORE TAG(INTEGER KK,SLINK)
ROUTINESPEC UNPACK
ROUTINESPEC PACK(INTEGERNAME PTYPE)
ROUTINESPEC RHEAD(INTEGER KK)
ROUTINESPEC RDISPLAY(INTEGER KK)
ROUTINESPEC ODDALIGN
INTEGERFNSPEC PTR OFFSET(INTEGER RLEV)
ROUTINESPEC PPJ(INTEGER MASK,N)
ROUTINESPEC REMEMBER
INTEGERFNSPEC REVERSE(INTEGER MASK)
INTEGERFNSPEC AREA CODE
INTEGERFNSPEC SET XORYNB(INTEGER WHICH,L)
INTEGERFNSPEC XORYNB(INTEGER USE,LEV)
ROUTINESPEC GET IN ACC(INTEGER A,B,C,D,E)
ROUTINESPEC NO APP
ROUTINESPEC DIAG POINTER(INTEGER L)
ROUTINESPEC COPY DR
ROUTINESPEC CHANGE RD(INTEGER REG)
ROUTINESPEC TEST ASS(INTEGER REG)
ROUTINESPEC NOTE ASSMENT(INTEGER REG,VAR)
SWITCH SW(1:13)
RECORDFORMAT RD(BYTEINTEGER UPTYPE,PTYPE,XB,FLAG,C 
 INTEGER D,XTRA)
INTEGER TWSPHEAD,SNDISP,ACC,K,KFORM
INTEGER TCELL,JJ,JJJ,KK,BASE,DISP,AREA,ACCESS, C 
 PTYPE,I,J,OLDI,USEBITS,ROUT,NAM,ARR,TYPE
INTEGERARRAY SGRUSE,SGRINF(0:7)
 TWSPHEAD=0
 ->SW(A(P))
SW(1): ! <STMNT><S>
 SET LINE IF PARMLINE#0
 IF LEVEL<=1 THEN FAULT(57,0) AND RETURN 
 NMDECS(LEVEL)=NMDECS(LEVEL)!1
 P=P+1; CSTMNT
CSSEXIT:
 WHILE TWSPHEAD#0 CYCLE 
 POP(TWSPHEAD,JJ,KK,JJJ)
 RETURN WSP(JJ,KK)
 REPEAT 
 RETURN 
SW(2): ! %END
 SET LINE IF PARMLINE#0
 IF A(P+1)=1 THEN FAULT(47,0)
 CEND(FLAG(LEVEL))
 RETURN 
SW(4): ! <TYPE'>%PROCEDURE<FPP><ETC>
 ->VDEC UNLESS A(P+2)=1
 FAULT(40,0) UNLESS NMDECS(LEVEL)=0
BEGIN 
RECORDNAME LCELL(LISTF)
INTEGER PNAME, EXTRN, Q, PP, PTYPEP, PARN, DISP, TYPEP, LINK, NP,C 
 LINEP, PE, PL, OPHEAD, AVHEAD, OPBOT
 P=P+1
 PP=P; PNAME=A(P+4); ! PROCEDURE NAME
 EXTRN=P+3+A(P+3); ! TO OLABEL
 PL=EXTRN
 WHILE A(EXTRN)=1 THEN EXTRN=EXTRN+3
 PE=EXTRN+1; ! TO ALT OF PROCSTMNT
 EXTRN=A(PE)
 IF LEVEL=1 AND CPRMODE=0 THEN CPRMODE=2 AND MAKE DECS(0,-1)
 COPY TAG(PNAME); Q=K
 LINEP=SNDISP
 P=PP
 UNLESS ROUT=1 AND OLDI=LEVEL THEN DECLARE PROC
 P=PP
 ->L99 IF EXTRN<=3 OR J=14
 IF LEVEL=1 THEN START 
 CPRMODE=2 IF CPRMODE=0
 FAULT(105, PNAME) IF CPRMODE#2
 JJ=ASLIST(Q)_S1
 DEFINE EP(STRING(DICTBASE+WRD(PNAME)), CA, JJ, 0)
 IF JJ#0 THEN PSF1(INCA,0,-JJ)
 DIAG POINTER(LEVEL+1)
 FINISH 
 COPY TAG(PNAME)
 LINK=K; Q=ACC
 JJ=LINK; NP=ASLIST(LINK)_S2; ! NO OF PARAMS
 PLABEL=PLABEL-1
 UNLESS CPRMODE=2 AND LEVEL=1 START 
 JROUND(LEVEL+1)=PLABEL
 ENTER JUMP(15,PLABEL, 0)
 FINISH 
 PTYPEP=PTYPE
 RHEAD(PNAME)
!
! CHANGE TAG TO 'BODY GIVEN' BY SETTING J=0 IN WORD 0 OF THE TAGS FIELD
!
 LCELL==ASLIST(TAGS(PNAME))
 LCELL_S1=LCELL_S1&X'FFFFFFF0'; ! AND OUT "J"(DIMEN) FIELD
!
! GO DOWN THE PARAMETER LIST OF THE PROCEDURE AND DECLARE THE
! PARAMETERS AS LOCAL VARIABLE AT THIS LEVEL
!
 MLINK(LINK); AVHEAD=0
 WHILE LINK#0 CYCLE 
 FROM123(LINK, TYPEP, PARN, DISP)
 J=PARN>>16; PTYPE=TYPEP
 IF PTYPE&X'F00'>X'100' THEN PTYPE=PTYPE&X'F0FF'!X'100'
 TYPE=PTYPE&7
 K=PARN&X'FFFF'; ACC=0; KFORM=LINK
! TEST NST; SNDISP=M'FP'
 ACC=BYTES(TYPE) IF TYPE<=3 AND PTYPE<4096
 IF PTYPE>=4096 START ; ! PROCEDURE PARAMETERS
 OPHEAD=0; OPBOT=0; JJ=J
 WHILE JJ>0 CYCLE 
 BINSERT(OPHEAD,OPBOT,ASLIST(JJ)_S1, C 
 ASLIST(JJ)_S2,ASLIST(JJ)_S3)
 MLINK(JJ)
 REPEAT ; J=0
 ASLIST(OPHEAD)_S1=(DISP&X'FFFF')
 DISP=OPHEAD
 FINISH 
 STORE TAG(K, DISP&X'FFFF')
 IF PTYPE&X'FF0'=X'10' START ; ! ARRAYS BY VALUE
 PUSH(AVHEAD,DISP,SIZECODE(PTYPE&7),0)
 FINISH 
 MLINK(LINK)
 REPEAT 
 N=Q; ! TOTAL SPACE OCCUPIED BY SAVE 
 !AREA AND PARAMS
 Q=PP+6
 PTYPE=PTYPEP
 RDISPLAY(PNAME)
 WHILE AVHEAD#0 CYCLE 
 POP(AVHEAD,DISP,JJ,JJJ)
 SAVE AUX STACK(1); ! ARRAYS ON STACK
 PLANT(X'1804'); ! PRCL 4
 PSF1(LSQ,1,DISP&X'FFFF')
 PLANT(X'4998'); ! ST TOS
 PLANT(X'7A00'!JJ); ! LB JJ(=ELSIZE IN BYTES)
 PLANT(X'6C09'); ! RALN 5
 PPJ(-1,13); ! CALL PERM SUBROUTINE
 PSF1(ST,1,DISP&X'FFFF')
 REPEAT 
 IF NP>0 THEN Q=Q+3*NP-1
 MAKE DECS(Q, PTYPEP)
 P=PL; COLABEL
 IF EXTRN=5 THEN START 
 P=PE+1; LINE=A(P)
 P=P+1; SET LINE IF PARMLINE#0
 CSTMNT
 CEND(FLAG(LEVEL))
 FINISH 
L99: END 
 ->CSSEXIT
VDEC:
SW(7): ! '%OWN' (TYPE)(OWNDEC)
 FAULT(40,0) UNLESS NMDECS(LEVEL)=0
 RETURN 
SW(5): ! %BEGIN
BEGIN 
INTEGER CORB,SIGEPNO
 CORB=A(P+1)
 PTYPE=0
 IF LEVEL=1 AND RLEVEL=0 THEN START 
 RLEVEL=1
 FAULT(105,0) IF CPRMODE#0
 CODE DES(JJ)
 DEFINE EP(MAINEP, CA, JJ, 1)
 L(1)=0; M(1)=0
 DIAGINF(1)=0; AUXSBASE(1)=0
 CPRMODE=1
 N=24; NMAX=N
 IF INCLUDE HANDCODE=NO THEN START 
 CYCLE I=0,1,7
 GRUSE(I)=0
 REPEAT 
 FINISH ELSE START 
 *LSQ_0
 *LCT_GRUSE+4
 *ST_(CTB +0)
 *ST_(CTB +4)
 FINISH 
 DIAGPOINTER(LEVEL+1)
!
! LAY DOWN A CONTINGENCY AGAINST ERROR IN PROGRAM
! IE COMPILE EXTERNAL CALL 'S#SIGNAL(0,PC,LNB,FLAG)'
!
 CXREF(SIGEP,PARMDYNAMIC,2,JJ); ! REFERENCE TO SIGNAL
!
! THE CODE PLANTED IS AS FOLLOWS:-
! LXN (LNB+4) TO GLA(PLT)
! STLN (XNB+5) SAVE LNB FOR STOP SEQUENCE
! ASF 1 FOR REPORT WORD
! PRCL 4 START OF STANDARD CALL
! LSS SIGEPNO 9 IN JOBBER MODE 0 OTHERWISE
! ST TOS FIRST PARAM
! JLK +3 2ND PARAM AND JUMP ROUND NEXT INSTR
! JCC 15,PERM15 TO RECOVERY SUBROUTINE
! STLN TOS 3RD PARAM
! LDTB WORD DES DESC USED FOR 'INTEGER()'
! LDA (XNB+5) ADD IN LNB
! INCA +20 TO WORD 5 OF FRAME(REPORT WORD)
! STD TOS 4TH AND LAST PARAM
! RALN 10
! CALL SIGREF
!
 PSF1(LXN,1,16)
 PF1(STLN,0,XNB,20)
 PSF1(ASF,0,1)
 PSF1(PRCL,0,4)
 IF PARMBITS1&JOBBERBIT#0 THEN SIGEPNO=9 ELSE SIGEPNO=0
 PSF1(LSS,0,SIGEPNO)
 PF1(ST,0,TOS,0)
 PSF1(JLK,0,3)
 PPJ(15,15)
 PF1(LDTB,0,PC,PARAM DES(1))
! PF1(STLN,0,TOS,0)
! PF1(LDA,0,XNB,20)
! PSF1(INCA,0,20)
! PF1(STD,0,TOS,0)
! PSF1(RALN,0,10)
! PF1(MPSR,0,0,X'40C0')
 PCLOD(37,40)
 PF1(CALL,2,XNB,JJ)
!
! SET THE PROGRAM MASK TO MASK OUT UNDERFLOW AND ALLOW ALL OTHER INTS
!
! MPSR X'40C0'
!
 PTYPE=1
 RHEAD(-1)
 RDISPLAY(-1)
 IF CORB=1 THEN START 
 P=P+2
 WHILE A(P)=1 THEN P=P+1; ! PAST COMMENTS
 P=P+1; COLABEL
! LINE=LINE+1
 SET LINE IF PARMLINE#0
 NMDECS(LEVEL)=NMDECS(LEVEL)!1
 CSTMNT
 FINISH ELSE MAKE DECS(P+2,-1)
 FINISH ELSE START 
 P=P+2
 IF CORB=1 THEN CCMPNDSTMNT ELSE START 
 RHEAD(-1)
 RDISPLAY(-1)
 MAKE DECS(P,-1)
 FINISH 
 FINISH 
END 
 ->CSSEXIT
SW(6): ! %SWITCH <NAME>:=<DE><RESTOFDELIST>
 FAULT(40,0) UNLESS NMDECS(LEVEL)=0
 BEGIN 
 INTEGER N,DIS,REP,I,PL,FLAG,SWNAME,J
 SWNAME=A(P+1)&X'FFFF'
 COPYTAG(SWNAME)
 REP=0; N=KFORM
 IF ARR=1 THEN START ; ! SWITCH NOT SIMPLE
 DIS=(K&X'FFFF')*4
 P=P+4
 PLABEL=PLABEL-1
 PL=PLABEL
 FLAG=B'10'
 ENTER JUMP(15,PL,FLAG)
 CYCLE I=0,1,N-1
 J=CA-DIS
 PLUG(1,DIS+4*I,J)
 IF INCLUDE HANDCODE=NO THEN START 
 CYCLE J=0,1,7
 GRUSE(J)=0
 REPEAT 
 FINISH ELSE START 
 *LSQ_0
 *LCT_GRUSE+4
 *ST_(CTB +0)
 *ST_(CTB +4)
 FINISH 
 CDE(2)
 P=P+2
 REPEAT 
 ENTER LAB(PL,B'110',LEVEL)
 FINISH 
 END 
 ->CSSEXIT
SW(8): ! <OLAB>:<SS>
 P=P+1; CLABEL; CSS(P)
SW(3): ! %COMMENT
 RETURN 
SW(10): ! %CODEON
SW(11): ! %CODEOFF
 IF ALLOW CODELIST=YES THEN START 
 CODEOUT
 DCOMP=(A(P)-1)&1
 FINISH 
 RETURN 
SW(13): ! %SPECIALNAME
 Q=A(P+1)
 PUSH(TAGS(Q),SNPT<<16!X'8000',0,SNUM<<16)
 SNUM=SNUM+1
 RETURN 
SW(9): ! <S>
 NMDECS(LEVEL)=NMDECS(LEVEL)!1
 RETURN 
SW(12): ! %PROGRAM (NAME)(S)
 FAULT(40,0) UNLESS CPRMODE=0
 Q=A(P+1)
 MAINEP<-STRING(DICTBASE+WRD(Q))
 RETURN 
 ROUTINE DECLARE OWNS
!***********************************************************************
!* OWN DECLARATION GO INTO THE GLA OR GLA SYMBOL TABLES *
!* ARRAYS HAVE A HEADER IN THE GLA. LPUT ARRANGES *
!* FOR THE LOADER TO RELOCATE THE HEADERS. *
!***********************************************************************
ROUTINESPEC CLEAR(INTEGER L)
ROUTINESPEC STAG(INTEGER J)
INTEGER LENGTH, BP, PP, ICONST1, ICONST2, TAGDISP, AH1, AH2, AH3, C 
 AH4, AD, NNAMES, PTYPEP, PTYPEPP, LB, APARM
 FAULT(40,0) IF NMDECS(LEVEL)&1#0
 P=P+3
 NAM=0; ARR=A(P)-1; ROUT=0
 ICONST1=0; ICONST2=0
 TYPE=A(P-1); TYPE=2 IF TYPE=4
 ACC=BYTES(TYPE); P=P+2
 PACK(PTYPE); PTYPEP=PTYPE
 ->NON SCALAR UNLESS ARR=0
!
 UNTIL A(P-1)=2 CYCLE ; ! DOWN <DECLIST>
 J=0; K=A(P)
 KFORM=0; AD=ADDR(ICONST1)
 PGLA(ACC, ACC, AD); ! PUT CONSTANT INTO GLA
 TAGDISP=GLACA-ACC; ! OFFSET OF VAR FOR TAGS
 STAG(TAGDISP)
 P=P+2
 REPEAT 
 RETURN 
NONSCALAR: ! OWN ARRAYS
!***********************************************************************
!* P<OADEC>:=<DECLIST><CBPAIR><RESTOFOADEC> *
!* P<RESTOFOADEC>:=','<OADEC>,%NULL *
!***********************************************************************
 P=P+1; PP=P; NNAMES=1; ! P TO START OF DECLIST
 APARM=A(P)
 WHILE A(P+1)=1 THEN APARM=APARM!A(P) AND C 
 P=P+2 AND NNAMES=NNAMES+1
 APARM=1-APARM>>16
 P=P+2; BP=ACC; PTYPEPP=PTYPEP
!
! NOW OUTPUT A DOPE VECTOR
!
 AH4=DOPE VECTOR(BP, APARM, LENGTH, LB)+12
 IF LB=0 AND J=1 THEN PTYPEPP=PTYPEPP+16;! SET ARR=2 NO DVM NEEDED
 UNTIL NNAMES=0 CYCLE 
 K=A(PP)&X'FFFF'
 USTPTR=(USTPTR+3)&(-4)
!
! OUTPUT AN ARRAYHEAD INTO THE GLA RELATIVE TO THE START OF THE SYMBOL-
! TABLES IN WHICH THE ARRAY RESIDES. THE LOADER WILL RELOCATE
! BY ADDING INTO AH1-3 THE VIRTUAL ADDRESS OF THE START OF THE
! APPROPIATE AREA.
!
 IF TYPE=2 THEN AH1=6 ELSE AH1=5
 AH1=AH1<<27!LENGTH
 AH2=USTPTR
 AH3=5<<27!3*J; ! DV DESCPTR = WORD + CHECKED
 CLEAR(LENGTH)
 PGLA(8, 16, ADDR(AH1))
 TAGDISP=GLACA-16
 RELOCATE(TAGDISP+4, AH2, 5);! RELOCATE ADDR(A(FIRST))
 RELOCATE(TAGDISP+12, AH4, 1);! RELOCATE DV POINTER
 NOTE CREF(((AH4<<1>>3)!X'80000000')!(TAGDISP+12)>>2<<16)
 PTYPE=PTYPEPP
 KFORM=0
 STAG(TAGDISP)
 PP=PP+2
 NNAMES=NNAMES-1
 REPEAT 
 IF A(P)=1 THEN P=P+2 AND ->NONSCALAR
 RETURN 
ROUTINE CLEAR(INTEGER LENGTH)
 LENGTH=(LENGTH+3)&(-4)
 LPUT(5, LENGTH, USTPTR, 0) IF INHCODE=0
 USTPTR=USTPTR+LENGTH
END 
ROUTINE STAG(INTEGER J)
INTEGER RL
! TEST NST
 RL=RLEVEL
 SNDISP=0
 RLEVEL=0
 STORE TAG(K, J)
 RLEVEL=RL
END 
END ; 
ROUTINE MAKE DECS(INTEGER PP, KK)
!***********************************************************************
!* PP TO LIST OF LIKS:- *
!* A(PP) = LINKS FOR LABELS, A(PP+1) = LINKS FOR SCALARS *
!* A(PP+2) = LINK FOR ARRAYS, A(PP+3) = LINK FOR SWITCHES *
!* A(PP+4) = LINK FOR OWN DECS,A(PP+5) = LINK FOR PROCEDURES *
!* A(PP+6) = COUNT OF BLKS & (LABELS IN INNER BLOCKS) *
!* KK <0 FOR BEGIN BLOCKS >0 FOR PROCEDURES *
!***********************************************************************
ROUTINESPEC DOWN LIST(INTEGER Q,LN,INC,ROUTINE DEC)
INTEGER SAVELINE, Q, QQ, ARRS, INTLABS, LABPARAMS, INNERBLKS
 SAVELINE=LINE
 ARRS=AUXSBASE(LEVEL)!A(PP+2); ! =0 IF THERE ARE NO ARRAYS TO BE
 ! DECLARED & THERE WERE NO ARRAYS
 ! PASSED BY VALUE
 LABPARAMS=PASS2INF&(LABBYNAME!SWBYNAME)
 INNERBLKS=A(PP+6)>>12
 INTLABS=A(PP)!A(PP+6)&X'FFF'; ! =0 IF NOLABS IN BLK OR SUBBLKS
!
! PROGRAMS AND EXTERNAL ROUTINES NEED A COPY OF AUX STACKTOP IN CASE
! A LABEL IS PASSED BY NAME INTO A SEPARATELY COMPILED ENTITY WHICH
! HAS DECLARED ARRAYS. IF PASS 2 REPORTS NO LABEL OR SWITCH PARAMETERS
! AND THERE ARE NO NESTED BLOCKS OR THIS BLOCK + ALL CONTAINED
! BLOCKS&PROCS HAVE NO LABELS THEN THIS CASE CAN NOT ARRISE
!
 IF LEVEL=2 AND (INTLABS#0 AND INNERBLKS!LABPARAMS#0) C 
 THEN SAVE AUX STACK(ARRS)
!
 DOWN LIST(PP+1,1,2,DECLARE SCALARS)
!
 DOWN LIST(PP+4,1,1,DECLARE OWNS)
!
 DOWN LIST(PP,0,3,DECLARE LAB)
!
 Q=PP+3; QQ=A(Q)
 IF QQ#0 START 
 CNOP(0,4); PLABEL=PLABEL-1
 ENTER JUMP(15,PLABEL,B'10')
 DOWN LIST(Q,1,3,DECLARE SWITCH)
 ENTER LAB(PLABEL,0,LEVEL)
 FINISH 
!
 DOWN LIST(PP+5,2,2,DECLARE PROC)
!
 Q=PP+2
 DOWN LIST(Q,2,2,DECLARE ARRAYS)
!
 LINE=SAVELINE
 Q=AUXSBASE(LEVEL)&X'3FFFF'
 IF Q#0 THEN START 
 IF ARRS#0 START 
!
! WE HAVE AN AUX STACK: DO WE NEED TO STORE THE AUGMENTED TOP?
! ONLY IF WE CAN PASS A LABEL FROM THIS OR INNER BLOCK OUT OR
! IF WE CAN JUMP INTO THIS(OR INNER)BLK FROM NESTED BLK
!
 IF INTLABS#0 AND INNERBLKS!LABPARAMS#0 THEN START 
 PSF1(LSS,2,Q) IF A(PP+2)=0;! NOT STILL GOT AUXSF IN ACC
 PSF1(ST,1,Q+12); ! ONLY USED AFTER JUMP OUT OF
 ! AN INNER BLK OR PROCEDURE
 FINISH 
 FINISH 
 FINISH ELSE AUXSBASE(LEVEL)=AUXSBASE(LEVEL-1)
!
! MUST STORE STACKTOP IN CASE THIS PROC IS REENTERED BY BY JUMPING OUT
! OF AN INNER BLOCK OR FN WHEN THE STACK MUST BE RESET. IF THE BLOCK
! HAS NO LABELS IN IT AND NO LABELS IN ANY INNER BLOCK CAN OMIT THIS
!
 IF KK>0 OR LEVEL=2 START 
!
! DO WE NEED TO STORE SF AT THIS POINT. YES FOR REASONS OF AUX STACK FRNT
!
 IF INTLABS#0 AND INNERBLKS!LABPARAMS#0 START 
 PSF1(STSF,1,N)
 STACKBASE(RLEVEL)=N
 N=N+4
 FINISH ELSE STACKBASE(RLEVEL)=-1
 FINISH 
 RETURN 
 ROUTINE DOWN LIST(INTEGER Q,LN,INC,ROUTINE DECLARE)
!***********************************************************************
!* SCANS DOWN A LINKED LIST OF ARS MAKING THE APPROPIATE *
!* DECLARATIONS. THIS BRINGS ALL DECLARATIONS INCLUDING PROCS *
!* TO THE FRONTOF THE BLOCK AND SIDESTEPS FORWARD REFS *
!***********************************************************************
INTEGER QQ
SPEC DECLARE
 QQ=A(Q)
 WHILE QQ#0 CYCLE 
 Q=Q+QQ-1
 IF LN=0 THEN LINE=SAVELINE C 
 ELSE LINE=A(Q-LN)
 P=Q; DECLARE
 Q=Q+INC
 QQ=A(Q)
 REPEAT 
END 
END 
ROUTINE DECLARE LAB
!***********************************************************************
!* THIS ROUTINE DECLARES ALL THE LABELS SO THAT A %GOTO CAN *
!* BE CLASSIFIED AS INTERNAL OR EXTERNAL IMMEDIATELY *
!***********************************************************************
 K=A(P+2); ! K IS NAME
 PTYPE=6; SNDISP=0
 KFORM=0; J=0; ACC=0
! TEST NST
 STORE TAG(K, 0)
END 
ROUTINE DECLARE SWITCH
!***********************************************************************
!* P IS TO ALT OF P(SS) *
!* THIS ROUTINE RESERVES SPACE IN THE SST FOR THE SWITCH AND *
!* DECLARES THE NAME BUT NO CODE IS GENERERATED *
!***********************************************************************
INTEGER I, N, MARK, D0, D1, SIMPLE, SWNAME
 SWNAME=A(P+2)&X'FFFF'; N=0; SIMPLE=1
 MARK=P+3
 UNTIL A(MARK)#1 CYCLE 
 N=N+1
 SIMPLE=0 UNLESS A(MARK+2)=2 AND A(MARK+3)=1 AND C 
 A(MARK+5)=3
 IF SIMPLE#0 START 
 COPY TAG(A(MARK+4))
 SIMPLE=0 UNLESS OLDI=LEVEL AND PTYPE=6
 FINISH 
 MARK=MARK+1+A(MARK+1)
 REPEAT 
 IF SIMPLE=0 THEN D0=5<<27!N ELSE D0=X'E0'<<24!(2*N)
 D1=CA
 PGLA(4,8,ADDR(D0)); ! DESCPTR TO SW IN PLT
 RELOCATE(GLACA-4,D1,1)
 SNDISP=GLACA>>2-2; KFORM=N
 J=1; K=SWNAME
 ACC=4; PTYPE=(SIMPLE+1)<<4!6; ! LABEL ARRAY
! TEST NST
 STORE TAG(K, CA>>2)
 MARK=P+3
 CYCLE I=1,1,N
 IF SIMPLE=0 THEN PCONST(0) ELSE ENTERJUMP(15,A(MARK+4),0)
 MARK=MARK+1+A(MARK+1)
 REPEAT 
END 
ROUTINE DECLARE PROC
!***********************************************************************
!* P TO TYPE OF PROCEDURE-1 *
!* SIDE CHAIN SET UP IN OPHEAD CONSISTS OF:- *
!* PTYPE, NAME AND DISPLACEMENT FOR EACH FORMAL PARAMETER *
!* FOR RTPARAMS THE TOP HALF OF NAME IS THE PARAMLIST *
!* THE TOP CELL HAS:- *
!* RTADDR , NO OF PARAMS AND INFO *
!* INFO 2**0 BIT SET IF PARAMS ARE SIMPLE *
!* 2**1 BIT SET IF THUNKS ARE REQUIRED *
!***********************************************************************
ROUTINESPEC CFP
ROUTINESPEC CFPARAMS(INTEGERNAME OPHEAD,OPBOT,INTEGERNAME NP)
ROUTINESPEC CVALLIST(INTEGERNAME OPHEAD,INTEGER MODE)
ROUTINESPEC CCOMMENT
ROUTINESPEC CTYPELIST(INTEGERNAME OPHEAD,INTEGER MODE)
ROUTINESPEC CHECK FPS(INTEGERNAME OPHEAD,INTEGER MODE)
INTEGER PNAME, TYPEP, INC, I, N, CELL, NP, LINK, EXTRN, OPBOT, C 
 OPHEAD, RTHEAD, EPNAME, SLINE
 SLINE=LINE
 OPHEAD=0; NP=0; OPBOT=0
 TYPEP=4096+A(P)&3
 P=P+1
 PNAME=A(P+3)
 P=P+4; INC=1; ! TO ALT OF FPP
 CFPARAMS(OPHEAD,OPBOT,NP)
 P=P+8; ! PAST 7 HOLES TO VALUE LIST
 CVALLIST(OPHEAD,0)
 CTYPELIST(OPHEAD,0)
 P=P+1 UNTIL A(P)=2
 P=P+1
 WHILE A(P)=1 THEN P=P+3; ! SKIP OLABEL (IF ANY)
 EXTRN=A(P+1); ! EXTRN VALUES SIGNIFY:
 ! 1=%ALGOL
 ! 2=%EXTERNAL(IE IMP)
 ! 3=%FORTRAN
 ! 4=%BEGIN
 ! 5=SIMPLE STATEMENT
 LINE=SLINE; ! FOR FAULTING FORMAL PMS
 CHECK FPS(OPHEAD,0)
 J=15; I=0
 IF EXTRN<=3 THEN START 
 J=14; EPNAME=PNAME
 IF A(P+2)=1 THEN EPNAME=A(P+3)
 CXREF(STRING(DICTBASE+WRD(EPNAME)),PARMDYNAMIC,2,I)
 FINISH ELSE START 
 IF LEVEL=1 THEN CODE DES(I)
 FINISH 
 PUSH(OPHEAD, I, NP, 0)
 K=PNAME; SNDISP=LINE; ACC=INC
 KFORM=0
 PTYPE=TYPEP
! TEST NST
 STORE TAG(K, OPHEAD)
 RETURN 
ROUTINE CFPARAMS(INTEGERNAME OPHEAD,OPBOT,INTEGERNAME NP)
!***********************************************************************
!* PUT THE NAMES BETWEEN BRACKETS INTO A LIST CHECKING THEY *
!* ARE NOT ALREADY THERE *
!***********************************************************************
 WHILE A(P)=1 CYCLE 
 P=P+INC; NP=NP+1
 K=A(P); ! NAME
 IF OPHEAD#0 AND FIND(K, OPHEAD)>=0 THEN FAULT(7, K) C 
 ELSE BINSERT(OPHEAD,OPBOT, 256, K, 0)
 ! TYPE=?NAME
 P=P+1; INC=2; ! P TO REST OF FPP
 REPEAT 
END 
ROUTINE CVALLIST(INTEGERNAME OPHEAD,INTEGER MODE)
!***********************************************************************
!* COMPILING THE VALUE LIST CONSISTS OF CHECKING EACH NAME HAS *
!* APPEARED IN FPLIST AND RESETING NAME FIELD IN THE TYPE WORD *
!* MODE=0 FOR COMPILING PROC STMNT,#0 FOR FUNNY COMMENT *
!***********************************************************************
 IF A(P)=1 THEN START ; ! IF THERE IS A VALUE LIST
 P=P+1 UNTIL A(P)=2 OR MODE#0;! PAST COMMENTS
 P=P+1; LINE=A(P)
 N=A(P+1); P=P+2
 CYCLE I=1, 1, N; ! DOWN THE NAMELIST
 K=A(P)
 CELL=FIND(K, OPHEAD)
 IF CELL>0 THEN ASLIST(CELL)_S1=0 ELSE FAULT(8, K)
 P=P+1
 REPEAT 
 FINISH ELSE P=P+1
END 
ROUTINE CTYPELIST(INTEGERNAME OPHEAD,INTEGER MODE)
!***********************************************************************
!* COMPILING THE TYPE DECLARATIONS IS SIMILAR TO THE VALUE LIST *
!* MODE IS ZERO WHEN COMPILING A PROC #0 FOR FUNNY COMMENT *
!***********************************************************************
INTEGER CELL,PIN,ACCP
RECORDNAME LC(LISTF)
 PIN=P
 WHILE A(P)=1 CYCLE ; ! WHILE (MORE) DECLARATIONS
 P=P+1 UNTIL A(P)=2 OR MODE#0
 P=P+1; LINE=A(P)
 P=P+1; CFP
 P=P+1
 UNTIL A(P-1)=2 CYCLE ; ! UNTIL NO MORE OF DECLIST
 K=A(P)&X'FFFF'
 CELL=FIND(K, OPHEAD)
 LC==ASLIST(CELL) UNLESS CELL<0
 IF CELL<0 OR LC_S1&X'F0FF'#0 C 
 THEN FAULT(9, K) ELSE START 
 I=LC_S1
 LC_S1=PTYPE!I
 IF PTYPE>=4096 AND MODE=0 START 
 CCOMMENT
 LC_S2=RTHEAD<<16!LC_S2
 FINISH 
 IF PTYPE<6 AND I#0 THEN ACCP=8 ELSE ACCP=ACC
 LC_S3=ACCP
 FINISH 
 P=P+2
 REPEAT 
 IF PTYPE>=4096 AND MODE=0 START ;! SKIP OVER FUNNY COMMENT
 IF A(P)=2 THEN P=P+1 ELSE P=P+1+A(P+1)
 FINISH 
 REPEAT 
END 
ROUTINE CHECK FPS(INTEGERNAME OPHEAD, INTEGER MODE)
!***********************************************************************
!* PASS DOWN THE LIST AGAIN CHECKING EVERYTHING HAS BEEN GIVEN *
!* A VALID TYPE AND ALSO ASSIGNING PARAMETER DISPLACEMENTS *
!***********************************************************************
RECORDNAME LC(LISTF)
 INC=20
 LINK=OPHEAD
 WHILE LINK>0 CYCLE 
 LC==ASLIST(LINK)
 PTYPE=LC_S1
 J=LC_S2
 I=LC_S3
 UNPACK
 IF TYPE=6 AND NAM=0 THEN START 
 LC_S1=PTYPE+256
 NAM=1
 WARN(3,J)
 FINISH 
!
! FAULT ANY VALUE PARAMETERS FOR FORTRAN
!
 IF NAM=0=MODE AND EXTRN=3 THEN FAULT (10,J)
 IF MODE=0 AND 2<=EXTRN<=3 AND ROUT=0 AND 1<=TYPE<=3 C 
 AND NAM#0 THEN NAM=EXTRN AND C 
 LC_S1=PTYPE+256*(EXTRN-1)
 FAULT(10, J) C 
 IF PTYPE=0 OR PTYPE=256 OR (ROUT=1 AND NAM=0) OR C 
 (MODE=0 AND EXTRN=3 AND (TYPE=6 OR C 
 (TYPE=5 AND EBCDIC=0)))
 J=0
 J=1 IF NAM=1 AND (ARR=0 OR TYPE=6)AND ROUT=0 AND TYPE#5
 LC_S3=INC!J<<16
 INC=INC+I
 LINK=LC_LINK
 REPEAT 
END 
ROUTINE CCOMMENT
!***********************************************************************
!* DEAL WITH FUNNY COMMENT SPECIFYING PARAMS FOR RT TYPES *
!***********************************************************************
INTEGER NNP,PP,LINEP,PTYPEP,ACCP,RTBOT
 NNP=0; PP=P
 PTYPEP=PTYPE; ACCP=ACC
 LINEP=LINE; RTHEAD=0; RTBOT=0
 P=P+2 WHILE A(P+1)=1; ! FIND END OF DECLIST
 P=P+2
 IF A(P)=1 THEN START ; ! THERE IS A COMMENT
 INC=2
 CFPARAMS(RTHEAD,RTBOT,NNP)
 P=P+1
 CVALLIST(RTHEAD,1)
 CTYPELIST(RTHEAD,1)
 LINE=LINEP
 CHECKFPS(RTHEAD,1)
 FINISH 
 PUSH(RTHEAD,0,NNP,0)
 P=PP; PTYPE=PTYPEP; ACC=ACCP
END 
ROUTINE CFP
!***********************************************************************
!* SETS PTYPE AND ACC FOR EACH ALT OF FORMAL PARAMETER *
!***********************************************************************
SWITCH ALT(1:7)
 ->ALT(A(P))
ALT(1): ! %LABEL
 PTYPE=6; ->SAC
ALT(2): ! %SWITCH
 PTYPE=22; ->SAC
ALT(3): ! %STRING
 PTYPE=5; ->SAC
ALT(4): !(TYPE')(VDECLN)
 TYPE=A(P+1); P=P+2
 ->ALT(A(P)+4)
ALT(5): ! '%ARRAY' (ADECLN)
 ARR=1; ROUT=0; NAM=0
 P=P+1; ACC=16
 TYPE=2 IF TYPE=4
 PACK(PTYPE); RETURN 
ALT(6): ! (TYPE')(PROCEDURE)
 ROUT=1; NAM=0; ARR=0; ACC=16
 TYPE=TYPE&3; P=P+1
 PACK(PTYPE); RETURN 
ALT(7): ! (TYPE)
 PTYPE=TYPE
 ACC=BYTES(PTYPE)
 P=P+1; RETURN 
SAC: ACC=8
 P=P+1
END 
END 
ROUTINE DECLARE SCALARS
!***********************************************************************
!* THIS ROUTINE DECLARES A LIST OF SCALARS FROM INFORMATION *
!* IN THE GLOBAL VARIABLES ROUT,NAM,ARR,TYPE & ACC.IT WORKS *
!* OUT ROUNDING FACTORS FOR ITSELF. *
!* P POINTS TO THE DECLIST ON ENTRY AND IS UPDATED. *
!***********************************************************************
INTEGER INC
 TYPE=A(P)
 ROUT=0; NAM=0; ARR=0
 P=P+4
 PACK(PTYPE); J=0
 INC=4; ACC=BYTES(TYPE)
 IF ROUT=0 AND ARR=0 THEN INC=BYTES(TYPE)
 IF N&7=0 AND (INC=8 OR INC=16) THEN ODD ALIGN
 UNTIL A(P-1)=2 CYCLE ; ! DOWN THE NAMELIST
 K=A(P)
! TEST NST
 SNDISP=0; KFORM=0
 STORE TAG(K, N)
 N=N+INC
 P=P+2
 REPEAT 
END 
ROUTINE DECLARE ARRAYS
!***********************************************************************
!* P IS AT P<ADECLN> IN *
!* *
!* P<ADECLN>=<NAMELIST> <BPAIR> <RESTOFDECLN> *
!* P<BPAIR> = <CBPAIR>,'('<EXPR>':'<EXRR><RESTOFBP>*')' *
!* *
!* ARRAYS WITH CONSTANT BOUNDS HAVE THEIR *
!* DOPE-VECTOR IN THE CONSTANT AREA AND MAY HAVE THEIR SPACE *
!* ALLOCATED AT COMPILE TIME AMONG THE SCALARS *
!* ALL OTHER ARRAYS HAVE A DOPE VECTOR AMONG THE LOCALS AND GET *
!* THEIR SPACE OFF THE STACK AT RUN TIME *
!* BOTH SORTS OF ARRAYS HAVE A FOUR WORD HEAD AND D-V TO EMAS *
!* SYSTEM STANDARDS *
!***********************************************************************
ROUTINESPEC CLAIM AS
INTEGER DVDISP, PP, DVF, ELSIZE, TOTSIZE, R, LBND, PTYPEPP, C 
 PTYPEP, ARRP, NN, ND, II, JJ, QQ, CDV, D0, D1, DESC, APARM
 SET LINE IF PARMLINE#0
 SAVE AUX STACK(1)
 TYPE=A(P)
 TYPE=2 IF TYPE=4
 NAM=0; ROUT=0; ADFLAG=1
 P=P+5
 ARRP=1; ARR=ARRP; PACK(PTYPEP)
 ELSIZE=BYTES(TYPE)
 DESC=SIZECODE(TYPE)<<27
START: NN=1; APARM=A(P); ! FIND NO OF NAMES IN NAMELIST
 PP=P; CDV=0; PTYPEPP=PTYPEP
 WHILE A(P+1)=1 THEN P=P+2 AND APARM=APARM!A(P) AND NN=NN+1
 APARM=1-APARM>>16; ! 0 IS PASSED ,1 NOT PASSED
 P=P+2; ! TO ALT OF P<BPAIR>
 IF A(P)=1 THEN ->CONSTDV; ! P<BPAIR> =<CBPAIR>
!
! NORMAL CASE - PLANT CODE TO SET UP DOPE-VECTOR AT RUN TIME
!
 ND=0; JJ=P; DVF=0; TOTSIZE=X'FFFF'
 UNTIL A(P)=2 CYCLE ; ! TILL NO MORE BPAIRS
 P=P+1; ND=ND+1; ! COUNT NO OF DIMENSIONS
 SKIP EXP(0); SKIP EXP(0)
 REPEAT 
 P=JJ; DVDISP=N; ! DVDISP IS D-V POSITION
 N=N+12*ND+12; ! CLAIM SPACE FOR THE D-V
 FAULT(37, 0) IF ND>12; ! TOO MANY DIMENSIONS
!
 D0=5<<27!3*ND; D1=12; ! DESCPTR FOR DV
 STORE CONST(JJ,8,D0,D1)
 PF1(LD,0,PC,JJ)
 PSF1(STD,1,DVDISP)
 GRUSE(DR)=0
!
 PLANT(X'6201'); ! LSS 1=M1 THE FIRST MULTIPLIER
 GRUSE(ACCR)=5; GRINF(ACCR)=1
 CYCLE II=ND,-1,1
 P=P+1
 QQ=DVDISP+12*II; ! TRIPLE FOR IITH DIMENSION
 PSF1(ST,1,QQ+4); ! STORE MULTIPLIER
 IF ND<=2 AND PARMARR=0 AND A(P)=2 AND A(P+2)=3 C 
 AND A(P+3)=2 AND A(P+4)=1 AND A(P+6)=2 AND C 
 0<=A(P+5)<=APARM AND II=ND START 
 PLANT(X'6200'); ! LSS 0
 GRUSE(ACCR)=0
 P=P+7; PTYPEPP=PTYPEPP+16
 FINISH ELSE CSEXP(ACCR,1,0);! LOWER BOUND
 PSF1(ST,1,QQ); ! STORED IN DV
 CSEXP(ACCR,1,0); ! UPPER BOUND
 PSF1(ISB,1,QQ)
 PF3(JAF,6,0,3); ! JUMP UNLESS NEGATIVE
 PLANT(X'627F'); ! LSS -1 SET UP -1 (ENSURES 0 ELEMENTS
 PLANT(X'E001'); ! IAD 1 CONVERT TO RANGE
 PSF1(IMY,1,QQ+4); ! RANGE*MULTIPLIER
 PSF1(ST,1,QQ+8); ! AND STORED IN DV
 GRUSE(ACCR)=0
 REPEAT 
 PSF1(IMY,0,ELSIZE)
 PSF1(ST,1,DVDISP+8)
 P=P+1
 -> DECL
CONSTDV: ! CONSTANT BOUNDS
 DVF=1; P=P+1; CDV=1
 DVDISP=DOPE VECTOR(ELSIZE, APARM, TOTSIZE, LBND); ! AND GENERATE A D-V
 ND=J
 IF LBND=0 AND ND<=2 THEN PTYPEPP=PTYPEPP+16
!
DECL: ! MAKE DECLN - BOTH WAYS
 IF N&7=0 THEN ODD ALIGN
 PTYPE=PTYPEPP
 J=ND
 CYCLE JJJ=0, 1, NN-1; ! DOWN NAMELIST
 IF DVF#0 THEN START ; ! ARRAY IS STRING OF LOCALS
 R=TOTSIZE//ELSIZE
 D0=DESC!R
 STORE CONST(D1,4,D0,0)
 PF1(LDTB,0,PC,D1)
 FINISH ELSE START 
 STORE CONST(D1,4,DESC,0)
 PF1(LDTB,0,PC,D1)
 PSF1(LDB,1,DVDISP+20)
 FINISH 
 PSF1(STD,1,N); ! ARRAY DESC TO HEAD
 GRUSE(DR)=0
 PSF1(LSS,2,AUXSBASE(LEVEL)&X'3FFFF')
 PSF1(ST,1,N+4)
 IF DVF#0 THEN QQ=PC ELSE QQ=LNB
 PSORLF1(LDRL,0,QQ,DVDISP)
 PSF1(STD,1,N+8)
 SNDISP=0
 GRUSE(DR)=0; GRUSE(ACCR)=0
!
 ACC=ELSIZE; ! RESET ACC AFTER DV CMPLD
 KFORM=0
 K=A(2*JJJ+PP)&X'FFFF'
! TEST NST
 STORE TAG(K, N)
 N=N+16
 CLAIM AS
 REPEAT 
 P=P+1; ! PAST REST OF ARRAYLIST
 IF A(P-1)=1 THEN P=P+2 AND ->START
 ADFLAG=0
 RETURN 
ROUTINE CLAIM AS
!***********************************************************************
!* CLAIM THE SPACE FOR AN ARRAY FROM STACK OR AUX STACK *
!***********************************************************************
INTEGER D
 IF CDV=1 THEN START 
 TOTSIZE=(TOTSIZE+3)&(-4)
 IF TOTSIZE<X'1FFFF' THEN PSF1(LSS,0,TOTSIZE) ELSESTART 
 STORE CONST(D,4,TOTSIZE,0)
 PF1(LSS,0,PC,D)
 FINISH 
 FINISH ELSE PSF1(LSS,1,DVDISP+8)
 GRUSE(ACCR)=0; GRINF(ACCR)=0
 IF PARMCHK#0 THEN START 
 PLANT(X'4998'); ! ST TOS
 PSF1(LB,2,AUXSBASE(LEVEL)&X'3FFFF')
 PLANT(X'E19C'); ! IAD BREG
 GRUSE(BREG)=0; GRINF(BREG)=0
 FINISH ELSE PSF1(IAD,2,AUXSBASE(LEVEL)&X'3FFFF')
 PLANT(X'49DC'); ! ST (%DR) STORE UPDATED POINTER
 IF PARMOPT#0 THEN PF1(ICP,1,0,2) AND PPJ(2,8)
 IF PARMCHK#0 START 
 PF1(LDTB,0,PC,PARAM DES(5))
 PLANT(X'7798'); ! LDB TOS
 PLANT(X'739C'); ! LDA BREG
 PF2(MVL,1,1,0,0,UNASSPAT&255)
 FINISH 
END 
END 
INTEGERFN DOPE VECTOR(INTEGER ELSIZE, APARM, INTEGERNAME ASIZE, LB)
!***********************************************************************
!* CONSTRUCTS THE DOPE-VECTOR FOR A CONSTANT ARRAY IN THE *
!* SHAREABLE SYMBOL TABLES AND RETURNS ITS DISPLACEMENT AS RESULT*
!* EVENTUALLY ALL NON DYNAMIC DOPE VECTORS SHOULD GO VIA HERE *
!* P IS TO ALT (MUST BE 1!) OF P<CBPAIR> *
!* DOPE VECTOR CONSISTS OF :- *
!* DESRIPTOR (SCALED WORD) POINTING AT FIRST TRIPLE BND=3*ND *
!* SIZE (IN BYTES OF ENTIRE ARRAY) FOR STACK ADJUSTMENT *
!* AND ND TRIPLES EACH CONSISTING OF:- *
!* LBI - THE LOWER BOUND OF THE ITH DIMENSION *
!* MI - THE STRIDE FOR THE ITH DIMENSION *
!* CBI THE UPPER CHECK =(UBI-LBI+1)*MI *
!* WHERE M1=1(SCALED ARRAYS) OR THE ELEMENT SIZE AND *
!* MI = M(I-1)*RANGE(I-1) *
!***********************************************************************
INTEGER I, JJ, K, ND, D, PP, M0, HEAD
RECORDNAME LCELL(LISTF)
INTEGERARRAY DV(0:39); ! ENOUGH FOR 12 DIMENSIONS
 ND=0; PP=P
 ND=ND+1 AND P=P+7 UNTIL A(P)=2
 P=PP
 M0=1
 CYCLE D=ND,-1,1
 CBPAIR(I, JJ)
 K=3*D
 IF PARMARR=0 AND D=ND<=2 AND 1<=I<=APARM THEN I=0
 DV(K)=I
 DV(K+1)=M0
 M0=M0*(JJ-I+1)
 DV(K+2)=M0
 REPEAT 
 P=P+1
!
 ASIZE=M0*ELSIZE
 DV(2)=ASIZE
 DV(1)=12
 DV(0)=5<<27!3*ND; ! DESPTR FOR DV
 LB=DV(3*ND)
 J=ND; ! DIMENSIONALITY FOR DECLN
 K=3*ND+2
 HEAD=DVHEADS(ND)
 WHILE HEAD#0 CYCLE 
 LCELL==ASLIST(HEAD)
 IF LCELL_S2=ASIZE AND LCELL_S3=DV(5) START 
 CYCLE D=0,1,K
 ->ON UNLESS DV(D)=CTABLE(D+LCELL_S1)
 REPEAT 
 RESULT =X'80000000'!4*LCELL_S1
 FINISH 
ON:
 HEAD=LCELL_LINK
 REPEAT 
 IF CONST PTR&1#0 THEN CONST HOLE=CONST PTR AND C 
 CONST PTR=CONST PTR+1
 I=4*CONST PTR!X'80000000'
 PUSH(DVHEADS(ND),CONSTPTR,ASIZE,DV(5))
 CYCLE D=0,1,K
 CTABLE(CONST PTR)=DV(D)
 CONST PTR=CONST PTR+1
 REPEAT 
 IF CONST PTR>CONST LIMIT THEN FAULT(107,0)
 RESULT =I
END 
!%ROUTINE TEST NST
!!***********************************************************************
!!* SEE IF NAME 'K' HAS BEEN DECLARED BEFORE AT THIS LEVEL *
!!***********************************************************************
!%INTEGER Q
! FNAME=K
! Q=TAGS(FNAME)
! FAULT(7, FNAME) %IF ASLIST(Q)_S1>>8&15=LEVEL
!%END
ROUTINE RT JUMP(INTEGER CODE,INTEGERNAME LINK)
!***********************************************************************
!* PLANTS A 'BAL' TO THE APPROPIATE ENTRY ADDRESS IN LINK *
!* IF ROUTINE HAS BEEN SPECIFIED BUT NOT DESCRIBED THE JUMP CAN *
!* NOT BE PLANTED AND IS LINKED INTO A LIST HEADED BY LINK *
!* TO AWAIT FILLING (BY ' RHEAD ') WHEN THE BODY IS GIVEN. *
!* THE FORMAT OF AN ENTRY IS :- *
!* S2(32 BITS) = ADDRESS OF JUMP TO BE FILLED *
!* THE CODING ASSUMES I,J&OLDI ARE SET UP FOR THE CALLED ROUTINE *
!***********************************************************************
INTEGER DP
 IF J=15 THEN START ; ! RT BODY NOT GIVEN YET
 PUSH(LINK, CODE<<24!3<<23, CA, 0)
 PCONST(X'01800000'!CODE<<24)
 FINISH ELSE START ; ! BODY GIVEN AND ADDRESS KNOWN
 DP=LINK-CA
 DP=DP//2+1 IF CODE=CALL
 PSF1(CODE,0,DP)
 FINISH 
END 
ROUTINE DIAG POINTER (INTEGER LEVEL)
!***********************************************************************
!* INSERT A POINTER TO THE DIAG TABLE INTO THE DESCRIPTOR IN *
!* IN DR AND STORE THE DESCRIPTOR IN ITS PROPER PLACE *
!***********************************************************************
 IF PARMTRCE#0 THEN START 
 PUSH(RAL(LEVEL),1,CA,LDB<<24!3<<23)
 PCONST(X'77800000'); ! LDB 0 LONG FORM FILLED LATER
 GRUSE(DR)=0
 FINISH 
 PLANT(X'5883'); ! STD (LNB+3)
END 
ROUTINE CEND(INTEGER KKK)
!***********************************************************************
!* DEAL WITH ALL OCCURENCES OF '%END' *
!* KKK=PTYPE(>=4096) FOR ROUTINES,FNS AND MAPS *
!* KKK=0 FOR ENDS OF '%BEGIN' BLOCKS *
!* KKK=-1 FOR BLOCKS AFTER %DO OR %ELSE *
!* KKK=-2 FOR BLOCKS AFTER %THEN (IE %ELSE IS VALID) *
!* KKK=-3 FOR THE HYPOTHETICAL BLOCK TO STOP JUMPS INTO %FOR *
!* %ENDOFPROGRAM IS REALLY TWO ENDS. THE FIRST IS THE USERS *
!* AND THE SECOND IS PERMS. KKK=2 FOR A RECURSIVE CALL OF CEND *
!* ON END OF PROGRAM TO DEAL WITH THE %END CORRESPONDING TO *
!* THE %BEGIN COMPILED IN THE INITIALISATION SEQUENCE *
!***********************************************************************
INTEGER KP, WK, JJ, KK, BIT
ROUTINESPEC DTABLE(INTEGER LEVEL)
 NMAX=N IF N>NMAX; ! WORK SPACE POINTER
!
! CLEAR OUT THE LABEL LIST FAULTING LABELS WITH JUMPS OUTSTANDING
! AS NOT SET AND COMMENTING ON LABELS NOT USED
!
 WHILE LABEL(LEVEL)#0 CYCLE 
 POP(LABEL(LEVEL), I, J, KP)
 IF J&X'FFFF'#0 THEN START 
 J=J&X'FFFF'
 CLEAR LIST(J)
 FINISH 
 REPEAT 
!
 WHILE TWSPHEAD#0 CYCLE 
 POP(TWSPHEAD,JJ,KK,BIT)
 RETURN WSP(JJ,KK)
 REPEAT 
 CYCLE J=1, 1, 4
 IF AVL WSP(J,LEVEL)#0 THEN C 
 CLEAR LIST(AVL WSP(J, LEVEL))
 ! RELEASE TEMPORARY LOCATIONS
 REPEAT 
!
!
! CLEAR DECLARATIONS - POP UP ANY GLOBAL NAMES THAT WERE REDECLARED
! DESTROY SIDE CHAINS FOR ROUTINES
! NB PROCEDURES WITH PROCEDURE PARAMS HAVE SECONDARY SIDECHAINS
!
! AT THE SAME TIME CONSTRUCTTHE DIAGNOSTIC TABLES
 DTABLE(LEVEL); ! OUTPUT DIAGNOSTIC TABLES
!
! CLAIM THE STACK FRAME BY FILLING THE ASF IN THE BLOCK ENTRY CODING.
!
 NMAX=(NMAX+7)&(-8)
 IF KKK=2 THEN RETURN 
 JJ=SET(RLEVEL)
 IF KKK>=4096 OR KKK=1 THEN START 
 WK=JJ>>18; JJ=JJ&X'3FFFF'
 KP=(ASF+12*PARMCHK)<<24!3<<23!(NMAX-WK+3)>>2
 PLUG(1,JJ,KP)
 FINISH 
!
! NOW PLANT THE BLOCK EXIT SEQUENCE
!
 IF KKK>=4096 THEN START ; ! PROCEDURE END
 JJ=KKK&7
 IF JJ#0 THEN START 
 IF JJ=2 THEN KP=2 ELSE KP=1
 IF GRUSE(ACCR)#10 OR WRD(GRINF(ACCR))#M(LEVEL) START 
 GET IN ACC(ACCR,KP,0,LNB,SET(RLEVEL)>>18);! LOAD RESULT
 IF PARMCHK#0 THEN TYPE=JJ AND TEST ASS(ACCR)
 FINISH 
 FINISH 
 RESET AUX STACK
 PLANT(X'3840'); ! EXIT -64
 FINISH 
 IF KKK<=0 THEN START ; ! BEGIN BLOCK EXIT
 JJ=AUXSBASE(LEVEL-1)
 IF JJ#AUXSBASE(LEVEL) THEN RESET AUX STACK
 IF PARMTRCE=1 AND KKK#-3 START ;! RESTORE DIAGS POINTERS
 PLANT(X'7883'); ! LD LNB+12
 DIAG POINTER(LEVEL-1)
 FINISH 
 FINISH 
 IF KKK>=0 THEN START 
 IF INCLUDE HANDCODE=NO THEN START 
 CYCLE JJ=0,1,7
 GRUSE(JJ)=0
 REPEAT 
 FINISH ELSE START 
 *LSQ_0
 *LCT_GRUSE+4
 *ST_(CTB +0)
 *ST_(CTB +4)
 FINISH 
 FINISH 
!
! RETURN TO PREVIOUS LEVEL PROVIDED THERE IS A VALID ONE !
!
 UNLESS LEVEL>2 OR (LEVEL=2 AND CPRMODE=2) THEN START 
 IF KKK=1 AND LEVEL=2 THEN KKK=2 C 
 ELSE FAULT(14, 0) AND STOP 
 FINISH 
 LEVEL=LEVEL-1
 IF KKK>=4096 THEN RLEVEL=RLEVEL-1
!
! RESTORE INFORMATION ABOUT THE (NEW) CURRENT LEVEL
!
 POP(LEVELINF, JJ, N,BIT)
 NMAX=N>>16 IF KKK>=4096
 N=N&X'7FFF'
 IF KKK=2 THEN PPJ(15,16) AND CEND(KKK)
 ! ROUND AGAIN FOR 'ENDOFPROGRAM'
!
! COMPLETE THE JUMP AROUND ALL NON-EXTERNAL ROUTINES EXCEPT WHEN
! %TRUSTEDPROGRAM IS IN OPERATION.
!
 IF KKK>=4096 AND (RLEVEL#0 OR CPRMODE#2) C 
 THEN ENTER LAB(JROUND(LEVEL+1), 0,LEVEL)
 RETURN 
!
! LAYOUT OF DIAGNOSIC TABLES
! ****** ** ********* ******
!
! THE BOUND FIELD OF PLT DESCRIPTOR STORED AT (LNB+3 & LNB+4) IF
! USED TO CONTAIN A DISPLACEMENT RELATIVE TO THE START OF SST OF THE
! DIAGNOSTIC TABLES FOR THE BLOCK OR ROUTINE BEING EXECUTED.
! A ZERO BOUND MEANS NO DIAGNOSTIC REQUESTED.(NB THIS MAY MEAN A DUMMY
! FIRST WORD IN THE SST).
! THE ABSOLUTE ADDRESS OF THE SST FOR THE CURRENT CODE SEGMENT WILL
! ALWAYS BE FOUND IN THE STANDARD 10 WORDS OF THE GLA/PLT
!
! FORM OF THE TABLES:-
!
! WORD 0 = LINE OF RT IN SOURCE PROG <<16 ! LINE NO POSN(FROM LNB)
! WORD 1 = (12 LANG DEPENDENT BITS)<<20 ! ENVIRONMENT
! (BIT X'20000000 SET IF EBCDIC MODE)
! WORD 2 = DISPLAY POSN (FROM LNB)<<16 ! RT TYPE INFO
! WORD 3 = ZERO FOR BLKS OR STRING(<=11BYTES) BEING THE
! RT NAME. THIS WILL TAKE WORDS 4 AND 5 IF NEEDED
! WORD 6 = LANGUAGE DEPENDENT INFO . IMP ON CONDITIONS ETC
!
! THE REST IS MADE UP OF VARIABLE ENTRIES AND THE SECTION IS TERMINATED BY
! A WORD OF X'FFFFFFFF'
!
! EACH VARIABLE ENTRY CONSISTS OF THE VARIABLE WORD FOLLOWED BY
! THE VARIABLE NAME AS A STRING. THE WORD CONSISTS OF
! BITS 2**31 TO 2**20 TYPE INFORMATION (MAY BE LANGUAGE DEPENDENT
! BIT 2**19 =0 UNDER LNB =1 IN GLA
! BITS 2**18 TO 2**0 DISPLACEMENT FROM LNB(GLA) IN BYTES
!
!
! THE ENVIRONMENT IS A POINTER (RELATIVE TO SST) OF THE NEXT OUTERMOST
! BLOCK OR A POINTER TO GLOBAL OWNS, EXTERNAL OR COMMON AREAS
! A ZERO MEANS NO ENCLOSING BLOCK. WORD1=WORD3=0 IS AN
! IMP MAIN PROGRAM AND WILL TERMINATE THE DIAGNOSTICS.
!
ROUTINE DTABLE(INTEGER LEVEL)
!***********************************************************************
!* THIS ROUTINE LOOKS AT THE DECLARATIONS FOR THE CURRENT LEVEL & *
!* SETS UP THE SEGMENT OF SHARABLE SYMBOL TABLES TO DESCRIBE THEM.*
!***********************************************************************
STRING (31) RT NAME
STRING (8) LOCAL NAME
INTEGER DPTR, LNUM, ML, KK, JJ, Q, S1, S2, S3, S4
RECORDNAME LCELL(LISTF)
INTEGERARRAY DD(0:1000); ! BUFFER FOR SEGMENT OF SST
!
! FILL ALL OUTSTANDING REFERENCES TO THIS DIAGS BLOCK
!
 WHILE RAL(LEVEL)#0 CYCLE 
 POP(RAL(LEVEL),Q,JJ,KK)
 IF KKK=-3 THEN PUSH(RAL(LEVEL-1),Q,JJ,KK) ELSE C 
 PLUG(Q,JJ,KK!SSTL)
 REPEAT 
 RETURN IF KKK=-3; ! NO DECS IN FOR BLOCKS
 PUSH(RAL(LEVEL-1),4,SSTL+4,EBCDIC<<29) IF PARMTRCE#0
 DD(0)=L(LEVEL)<<16!(DIAGINF(LEVEL)+4)
 DD(1)=EBCDIC<<29
 DD(2)=DISPLAY(RLEVEL)<<16!FLAG(LEVEL)
 ML=M(LEVEL); ! ROUTINE NAME(=0 FOR %BEGIN)
 LNUM=BYTEINTEGER(DICTBASE+ML); ! LENGTH OF THE NAME
 DPTR=4
 IF LNUM=0 THEN DD(3)=0 ELSE START 
 Q=DICTBASE+ML
 RT NAME<-STRING(Q); ! FOR RTS MOVE IN 1ST 32 CHARS
 STRING(ADDR(DD(3)))=RTNAME; ! AND UPDATE POINTER PAST
 LNUM=BYTE INTEGER(ADDR(RT NAME))
 DPTR=DPTR+LNUM>>2; ! ACTUAL NO OF CHARS
 FINISH 
!
! FOR TYPED PROCEDURES ADD THE RESULT VARIABLE TO THE DIAG TABLES
!
 IF KKK>4096 AND PARMDIAG#0 START 
 TYPE=KKK&7
 DD(DPTR)=SIZECODE(TYPE)<<24!TYPE<<20!C 
 SET(RLEVEL)>>18
 LOCAL NAME<-RT NAME
 LNUM=BYTEINTEGER(ADDR(LOCAL NAME))
 STRING(ADDR(DD(DPTR))+4)=LOCAL NAME
 DPTR=DPTR+(LNUM+8)>>2
 FINISH 
 JJ=NAMES(LEVEL)
 WHILE 0<=JJ<X'3FFF' CYCLE 
 LCELL==ASLIST(TAGS(JJ))
 S1=LCELL_S1; S2=LCELL_S2
 S3=LCELL_S3; S4=LCELL_LINK
 LCELL_LINK=ASL; ASL=TAGS(JJ)
 TAGS(JJ)=S4&X'3FFFF'
 IF S1&X'C000'=0 THEN WARN(2,JJ)
 PTYPE=S1>>16
 IF PTYPE=6 AND S2&X'FFFF'#0 THEN FAULT(12,JJ)
 IF PTYPE&X'F000'#0 THEN START 
 K=S3>>16
 POP(K,KK,KK,KK)
 WHILE K>0 CYCLE 
 KK=ASLIST(K)_S2>>16; ! SECONDARY CHAIN IF PROCEDURE
 IF ASLIST(K)_S1>=4096 THEN CLEAR LIST(KK)
 POP(K,KK,KK,KK)
 REPEAT 
 FINISH 
 IF PARMDIAG#0 AND DPTR<997 AND 1<=PTYPE&X'F00F'<=5 START 
 IF PTYPE=5 THEN NAM=1 ELSE NAM=PTYPE>>8&3
 TYPE=PTYPE&7; ARR=PTYPE>>4&3
 Q=DICTBASE+WRD(JJ); ! ADDRESS OF NAME
 IF S1>>4&15=0 THEN I=1 ELSE I=0
 DD(DPTR)=NAM<<30!ARR<<28!SIZECODE(TYPE)<<24! C 
 TYPE<<20!I<<18!S3>>16
 LOCAL NAME<-STRING(Q);! TEXT OF NAME FROM DICTIONARY
 LNUM=BYTE INTEGER(ADDR(LOCAL NAME))
 STRING(ADDR(DD(DPTR))+4)=LOCAL NAME; ! MOVE IN NAME 
 DPTR=DPTR+(LNUM+8)>>2
 FINISH 
 JJ=S4>>18
 REPEAT 
 DD(DPTR)=-1; ! 'END OF SEGMENT' MARK
 DPTR=DPTR<<2+4
 IF PARMTRCE=1 AND KKK#-3 THEN START 
 LPUT(4, DPTR, SSTL, ADDR(DD(0)));! ADD TO SHARABLE SYM TABS
 SSTL=SSTL+DPTR
 FINISH 
END ; ! OF ROUTINE DTABLE
END 
ROUTINE SAVE AUX STACK(INTEGER ARRS)
!***********************************************************************
!* COPY THE AUX STACK DESCRIPTOR UNDER LNB AND SAVE THE STACK PTR*
!* FOUR WORDS ARE NEEDED TO SAVE THE AUXILLARY STACK STATUS *
!* 1&2 HOLD A COPY OF THE STACK DESCRIPTOR(FOR CONVENIENCE) *
!* 3 HAS COPY OF STACKTOP ON ENTRY(FOR RESETTING ON EXIT) *
!* 4 HAS COPY OF STACKTOP AFTER DECLARATIONS. NEEDED ONLY IF *
!* THE INNER BLOCKS ARE JUMPED OUT OF INTO CURR BLK *
!***********************************************************************
 IF AUXSBASE(LEVEL)=0 START 
 IF N&7=0 THEN ODD ALIGN
 AREA=-1; BASE=0
 GET IN ACC(DR,2,2,AREA CODE,AUXST)
 PLANT(X'63DC'); ! LSS @DR
 GRUSE(ACCR)=0
 PSF1(STD,1,N)
 PSF1(ST,1,N+8)
 IF ARRS=0 THEN C 
 PSF1(ST,1,N+12); ! IF NO ARRAYS LAST 2 WORDS
 ! ARE IDENTICAL
 AUXSBASE(LEVEL)=RLEVEL<<18!N
 N=N+16
 FINISH 
END 
ROUTINE RESET AUX STACK
!***********************************************************************
!* IF ANY ARRAYS HAVE BEEN PUT ON THE AUXSTACK THEN UNDECLARE *
!***********************************************************************
 IF AUXSBASE(LEVEL)>>18=RLEVEL START 
 PSF1(LB,1,AUXSBASE(LEVEL)&X'3FFFF'+8)
 PSF1(STB,2,AUXSBASE(LEVEL)&X'3FFFF')
 GRUSE(BREG)=0
 FINISH 
END 
ROUTINE RHEAD(INTEGER KK)
!***********************************************************************
!* COMPILES CODE FOR BLOCK AND ROUTINE ENTRY *
!* KK IS THE RT/FN/MAP NAME (=-1 FOR %BEGIN BLOCKS) *
!* THE FIRST (PERM) BEGIN WHICH HAS TO BE TREATED AS A ROUTINE *
!***********************************************************************
INTEGER W1, W3, INSRN, AT
 PUSH(LEVELINF, 0, NMAX<<16!N, 0)
 LEVEL=LEVEL+1
 NMDECS(LEVEL)=0
 AUXSBASE(LEVEL)=0; NAMES(LEVEL)=-1
 DIAGINF(LEVEL)=DIAGINF(LEVEL-1)
 IF KK>=0 THEN START 
 RLEVEL=RLEVEL+1
 FINISH 
 FAULT(34, 0) IF LEVEL=MAX LEVELS
 FAULT(108, 0) IF LEVEL>MAX LEVELS
 IF KK>=0 AND LEVEL>2 START ; ! ROUTINE ENTRY
 COPY TAG(KK); JJ=K; ! LIST OF JUMPS
 IF J=15 THEN START ; ! CHECK BODY NOT GIVEN
 J=ASLIST(JJ)_S1
 IF J=0 AND LEVEL>2 START ;! REPLACE 'NOT USED' BIT
 W1=TAGS(KK)
 ASLIST(W1)_S1=( ASLIST(W1)_S1&X'FFFF3FFF')
 FINISH 
!
! NOW FILL ANY JUMPS TO THIS ROUTINE PLANTED SINCE
! THE ROUTINESPEC WAS COMPILED. SEE ALSO 'RT JUMP'
! SOME CHECKS ARE MADE IN THE CASE THE LIST IS SCREWED UP BY IDIOT
! GIVING THE PROCEDURE BODY TWICE
!
 WHILE 0<J<=ASLMAX CYCLE 
 POP(J, INSRN, AT, W1)
 EXIT UNLESS 0<AT<CA
 W3=CA-AT
 W3=W3//2+1 IF INSRN>>25=CALL>>1
 INSRN=INSRN+W3
 PLUG(1, AT, INSRN)
 REPEAT 
 ASLIST(JJ)_S1=( CA); ! NOTE ADDR FOR FUTURE CALLS
 FINISH 
 FINISH 
 IF KK<0 THEN W3=0 ELSE W3=WRD(KK)
 L(LEVEL)=LINE; M(LEVEL)=W3
 FLAG(LEVEL)=PTYPE; ! CURRENT BLOCK TYPE MARKER
END ; ! OF ROUTINE RHEAD
ROUTINE RDISPLAY(INTEGER KK)
!***********************************************************************
!* SET UP OR COPY THE DISPLAY (A WORD ARRAY CONTAINING COPIES OF *
!* LNB FOR THE GLOBAL LEVELS. THE HIGHEST LEVEL ENTRY IS TO THE *
!* GLA(PLT) FOR OWNS AND IS ALSO KEPT IN(LNB+4) IN CASE WE WISH * 
!* TO MOVE TO READ-ONLY PLTS. ON INTERNAL CALLS THE LNB FOR THE *
!* NEXT MOST GLOBAL LEVEL IS STACKED AS AN EXTRA PARAMETER *
!***********************************************************************
INTEGER W1,W2,STACK,OP,INC
 IF KK>=0 OR LEVEL=2 START ; ! DISPLAY NEEDED
 STACK=0; DISPLAY(RLEVEL)=N
 IF LEVEL#2 THEN START 
 PF1(LXN,0,TOS,0)
 GRUSE(XNB)=4; GRINF(XNB)=RLEVEL-1
 GRUSE(CTB)=0
 PCONST(X'798C0003'); ! LD (XNB+3) COPY PLT DESRPTR
 DIAG POINTER(LEVEL)
 W1=RLEVEL-1; W2=DISPLAY(W1)
 IF W1=1 THEN PLANT(X'4D98') AND N=N+4 ELSE START 
 WHILE W1>0 CYCLE 
 OP=LSS; INC=1
 IF W1>=2 THEN OP=LSD AND INC=2
 IF W1>=4 THEN OP=LSQ AND INC=4
 PF1(OP+STACK,0,XNB,W2)
 STACK=-32; N=N+4*INC
 W2=W2+4*INC; W1=W1-INC
 REPEAT 
 FINISH 
 FINISH 
 IF STACK#0 THEN PLANT(X'4998'); ! ST TOS
 PLANT(X'5D98'); ! STLN TOS
 N=N+4
 FINISH 
!
! IF IN DIAGNOSTIC MODE PLANT CODE TO SAVE THE LINE & ROUTINE NO OF
! THE CALLING ROUTINE AND SET UP THE NEW BLOCK/ROUTINE IDENT NO.
!
 IF PARMTRCE#0 START 
 DIAGINF(LEVEL)=N
 PF1(LSS,0,PC,4*CONST BTM!X'80000000')
 IF KK>=0 OR LEVEL=2 START 
 PSF1(SLSS,0,LINE)
 PLANT(X'4998'); ! ST TOS
 FINISH ELSE START 
 PSF1(ST,1,DIAGINF(LEVEL))
 PSF1(LSS,0,LINE)
 PSF1(ST,1,DIAGINF(LEVEL)+4)
 PLANT(X'7883'); ! LD LNB+12
 DIAGPOINTER(LEVEL)
 FINISH 
 N=N+8
 GRUSE(ACCR)=0; ! NEEDED FOR %BEGIN BLOCKS
 FINISH 
!
! IN SEPARATELY COMPILED PROCEDURES CHECK THE CORRECT AMOUNT OF PARAMS
! ARE PRESENT ON THE STACK. THIS IS THE BEST POSSIBLE AT THIS DATE
!
 IF PARMOPT#0 AND KK>=0 AND LEVEL=2 START 
 PLANT(X'5F9C'); ! STSF BREG
 PLANT(X'5D98'); ! STLN TOS
 PLANT(X'2398'); ! SBB TOS
 PSF1(CPB,0,N)
 PPJ(7,10)
 FINISH 
!
! CLAIM (THE REST OF) THE STACK FRAME
!
 IF KK>=0 OR LEVEL=2 START 
 SET(RLEVEL)=N<<18!CA
 NMAX=N
 PCONST((ASF+12*PARMCHK)<<24!X'01800000');! ASF 0 OR LB 0
 PPJ(0,3) IF PARMCHK#0
 IF KK>=0 AND PTYPE&7#0 THEN N=N+8; ! FOR RESULT
 FINISH 
!
 IF KK>=0 AND PARMOPT#0 THEN START 
!
! STSF TOS GET STACK POINTER
! LSS TOS
! USH +14
! USH -15 LOSE SEGMENT NO
! ICP X'1F800' CHECK WITHIN SEG ADDRESS
! SHIFTED DOWN 1 PLACE
! JCC 2,EXCESS BLKS
!
 PCONST(X'5F986398'); ! STSF TOS LSS TOS
 PCONST(X'C80EC871'); ! USH 14 USH -15
 PCONST(X'E7800000'!ST LIMIT>>1);! ICP ST LIMIT>>1
 PPJ(2,8)
 FINISH 
END 
ROUTINE CLABEL
!***********************************************************************
!* P POINTS TO <NAME> IN <NAME><HOLE> *
!***********************************************************************
INTEGER LNAME,T,USE
 LNAME=A(P)
 IF LEVEL>1 THEN START ; ! LABELS BEFORE 1ST BEGIN
 T=TAGS(LNAME); USE=ASLIST(T)_S1
 UNLESS USE>>16=6 AND ASLIST(T)_S3=0 THEN C 
 FAULT(2,LNAME) ELSE ENTER LAB(LNAME,0,USE>>8&63);! USE>>8&63=OLDI
 FINISH 
 P=P+2
END 
ROUTINE COLABEL
!***********************************************************************
!* P POINTS TO ALT OF P<OLABEL> *
!***********************************************************************
 WHILE A(P)=1 THEN P=P+1 AND CLABEL
 P=P+1
END 
ROUTINE CBLK(INTEGER BLKTYPE)
!***********************************************************************
!* SUCK IN A BLOCK OCCURRING IN IF..THEN ETC *
!***********************************************************************
INTEGER I,OLDLEV,KK
 KK=0
 CYCLE I=P,1,P+5; KK=KK+A(I); REPEAT 
 IF KK=0 THEN BLKTYPE=-3
 PTYPE=BLKTYPE
 OLDLEV=LEVEL; RHEAD(-1)
 IF BLKTYPE=-3 THEN START 
 AUXSBASE(LEVEL)=AUXSBASE(LEVEL-1)
 FINISH ELSE START 
 RDISPLAY(-1)
 MAKE DECS(P,-1)
 FINISH 
 CYCLE ; ! TILL CORRESPONDING END
 I=NEXTP; NEXTP=NEXTP+A(NEXTP)
 IF ALLOW CODELIST=YES AND DCOMP#0 AND CA>CABUF THEN C 
 CODEOUT AND PRINT USE
 LINE=A(I+1)
 P=I+2
 WHILE A(P)=8 THEN P=P+1 AND CLABEL
 IF A(P)=2 AND LEVEL=OLDLEV+1 START 
 SET LINE IF PARMLINE#0
 CEND(BLKTYPE); ! BLKTYPE=FLAG(LEVEL)
 EXIT ; ! NOW COMPLETED THE BLOCK
 FINISH ELSE CSS(P)
 REPEAT 
 P=P+1; ! TO ELSE AFTER %END
 END 
ROUTINE CCMPNDSTMNT
!***********************************************************************
!* SUCK IN A COMPOUND STATEMENT (IE BLOCK WITH NO DECLNS) *
!* P TO PHRASE <OPTCOM> IN THE SEQUENCE:- *
!* '%BEGIN'<OPTCOM><OLABEL><STMNT> *
!***********************************************************************
INTEGER I,OLDLEVEL
 OLDLEVEL=LEVEL
 WHILE A(P)=1 THEN P=P+1; ! PAST ANY COMMENTS
 P=P+1; COLABEL
! LINE=LINE+1
 SET LINE IF PARMLINE#0
 CSTMNT
 CYCLE 
 I=NEXTP; NEXTP=NEXTP+A(NEXTP)
 IF ALLOW CODELIST=YES AND DCOMP#0 AND CA>CABUF THEN C 
 CODEOUT AND PRINT USE
 LINE=A(I+1)
 P=I+2
 WHILE A(P)=8 THEN P=P+1 AND CLABEL
 IF LEVEL=OLDLEVEL AND A(P)=2 THEN EXIT 
 CSS(P)
 REPEAT 
 P=P+1; ! TO ELSE IF ANY
END 
ROUTINE C FORSTMNT
!***********************************************************************
!* COMPILE A FOR STATEMENT TREATING SIMPLE CASES WELL *
!***********************************************************************
ROUTINESPEC C FORLISTEL
ROUTINESPEC INTO FOR
ROUTINESPEC C FOR BODY
INTEGER FORNAME,FORLISTE,FORTYPE,FORPTYPE,FPL,FP,FCMPLX,FBP
 FBP=P+2+A(P+2)
 FORLISTE=A(FBP); ! =2 IF ONE ELEMENT LIST
 IF FORLISTE=2 THEN START 
 FBP=FBP+1
 WHILE A(FBP)=1 THEN FBP=FBP+3
 FBP=FBP+1
 FINISH 
 FORNAME=A(P+3)
 FP=P+3; P=FP+1
 COPYTAG(FORNAME)
 FCMPLX=ROUT!NAM!ARR!PARMCHK!(TYPE//7);! CATCH NAME NOT SET
 FAULT(25,FORNAME) UNLESS (1<=TYPE<=2 OR TYPE=7) AND C 
 ARR=ROUT=0 AND A(P)=3
 TYPE=1 AND PTYPE=1 UNLESS 1<=TYPE<=2 OR TYPE=7;! BOOLEANS HERE CAUSE HAVOC
 FORTYPE=TYPE; FORPTYPE=PTYPE
 IF A(P)#3 THEN SKIP APP AND P=P-1
 PLABEL=PLABEL-1; FPL=PLABEL
 UNTIL FORLISTE=2 OR A(P)=2 CYCLE ;! UNTIL FORLIST EXHAUSTED
 P=P+1; C FORLISTEL
 REPEAT 
 IF FORLISTE#2 THEN P=P+1 AND C FORBODY
 RETURN 
ROUTINE C FORLISTEL
!***********************************************************************
!* COMPILE ONE ELEMENT OF A FOR LIST *
!* P TO <EXPR><RESTOFFLE> *
!***********************************************************************
INTEGER PP, FALT,QQ,FEXITPL,STEPP,STEPTMP,STEPRP,CONTROLRP,CNSTSTEP,C 
 STEPVAL,COPCODE,CXTRA,STEPHEAD,ASSHEAD,OPHEAD,NOPS,NSE,OPBOT,C 
 ASSBOT,STEPBOT,FETYPE,RR,FINACC,FINAREA,FINDISP,FINBASE,RRR,CPI
SWITCH FALTNO(1:3)
 OPHEAD=0; CNSTSTEP=0; STEPVAL=0
 ASSHEAD=0; STEPHEAD=0; NSE=0; CPI=0
 STEPBOT=0; OPBOT=0; ASSBOT=0
 PLABEL=PLABEL-1; QQ=PLABEL
 PLABEL=PLABEL-1; FEXITPL=PLABEL
 RR=RPPTR
 CONTROLRP=FORTYPE<<16!FCMPLX<<8!2
 NOPS=1; ETORP(OPHEAD,NOPS,FORTYPE)
 RRR=RPPTR-3
 A(RRR)=99
 A(RRR+1)=RPPTR; ! TIC TO NEXT =NO-OP
 A(RPPTR)=FORPTYPE<<16!2
 A(RPPTR+1)=FP
 A(RPPTR+2)=TAGS(FORNAME)
 A(RPPTR+3)=31; ! 31=ASSIGN
 RPPTR=RPPTR+6
 FALT=A(P); FETYPE=TYPE
 P=P+1
 ->FALTNO(FALT)
FALTNO(1): ! STEP -UNTIL
!
! FIRST CHECK FOR CONSTANT STEPS WHICH DO NOT NEED TO BE EVALUATED
! OR ASSIGNED TO TEMPORARIES
!
 IF A(P)=2 AND A(P+3)=2 AND A(P+4)=1 AND A(P+5)#0 C 
 AND A(P+6)=2 THEN START 
 CNSTSTEP=1; STEPVAL=A(P+5)
 IF A(P+2)=2 THEN STEPVAL=-STEPVAL
 P=P+7
 STEPRP=1<<16!1
 STEPTMP=STEPVAL
 IF FCMPLX=0 AND FORTYPE=FETYPE THEN NSE=1
 ! NO SIDE EFFECTS IN INCREMENTING
 IF NSE=FORTYPE=1 AND PARMOPT=0 AND A(P)=2 AND C 
 A(P+1+A(P+1))=2 START 
 IF A(P+3)=2 AND A(P+4)=1 START 
 FINDISP=A(P+5); FINACC=0; FINAREA=0; FINBASE=0
 IF A(P+2)=2 THEN FINDISP=-FINDISP
 IF IMOD(FINDISP)>>18=0 THEN ->CPIB
 FINISH 
!
 IF A(P+3)=1 AND A(P+5)=3 START ; ! NAME --NO APP
 COPYTAG(A(P+4))
 IF PTYPE&X'FEFF'=1 START ;! OMIT NAM BIT
 FINACC=PTYPE>>7; ! 0 FOR LOCAL-2 FOR NAMETYPE
 FINAREA=-1; FINDISP=K
 FINBASE=I; ->CPIB
 FINISH 
 FINISH 
 FINISH 
 FINISH ELSE START 
 GET WSP(STEPTMP,FORTYPE); ! TEMPORARY FOR STEP
 STEPRP=FORTYPE<<16!LNB<<12!7;! REVERSE POLISH DESCRPTR
 FINISH 
!
! EVALUATE STEP AND ASSIGN TO TEMPORARY
!
 STEPP=P
 IF CNSTSTEP=0 THEN START 
 NOPS=NOPS+1; ETORP(STEPHEAD,NOPS,FORTYPE)
 A(RPPTR-3)=STEPRP
 A(RPPTR-2)=STEPTMP
 A(RPPTR)=31
 RPPTR=RPPTR+3
 FINISH 
 IF NSE#0 START 
 A(RRR+6)=30; ! REPLACE 31(:=) BY 30(::=)
 A(RRR)=12; ! MOVE LABEL TO ST INSTN
 A(RRR+1)=QQ!1<<16; ! AND FORCE A LOAD
 FINISH ELSE START 
 A(RPPTR)=12
 A(RPPTR+1)=QQ
 RPPTR=RPPTR+3
 FINISH 
!
! EVALUATE (V-C)*SIGN(D)
!
 COPCODE=27; CXTRA=5; ! '<='
 IF STEPVAL<0 THEN CXTRA=2; ! '>='
 IF NSE=0 START 
 A(RPPTR)=CONTROLRP
 A(RPPTR+1)=FP
 RPPTR=RPPTR+3
 FINISH 
!
 NOPS=NOPS+3
 ETORP(ASSHEAD,NOPS,FORTYPE)
 RPPTR=RPPTR-3
 IF CNSTSTEP=0 THEN COPCODE=16
 A(RPPTR)=COPCODE
 A(RPPTR+1)=CXTRA
 RPPTR=RPPTR+3
!
 IF CNSTSTEP=0 THEN START 
 A(RPPTR)=STEPRP
 A(RPPTR+1)=STEPTMP
 RPPTR=RPPTR+3
 A(RPPTR)=14; ! SIGN
 A(RPPTR+3)=19; ! MULTIPLY
 RPPTR=RPPTR+6
 FINISH 
 A(RPPTR)=100; ! TERMINATE
 RPPTR=RPPTR+3
 PP=P; EXPOP(RR,ACCR,NOPS,FORTYPE)
 P=PP; RPPTR=RR
 IF COPCODE=16 START 
 IF CNSTSTEP#0 AND STEPVAL<0 THEN MASK=18 ELSE MASK=17
 IF FORTYPE=1 THEN MASK=MASK+4
 FINISH 
 ENTER JUMP(MASK,FEXITPL,B'10')
COMM: INTO FOR
 IF CPI#0 START 
 P=FP; CSEXP(BREG,1,2); ! EXPRESSION OF SINGLE NAME
 FINISH ELSE START 
!
! INCREMENT CONTROL BY STEP
!
 P=STEPP; NOPS=1
 IF CNSTSTEP=0 THEN START 
 ETORP(OPHEAD,NOPS,FORTYPE); 
 RPPTR=RPPTR-3; ! EVALUATE STEP
 FINISH 
 A(RPPTR)=STEPRP
 A(RPPTR+1)=STEPTMP
 RPPTR=RPPTR+3
!
 IF CNSTSTEP=0 START 
 A(RPPTR)=30; ! ASSIGN VARIABLE STEP TO TEMP
 RPPTR=RPPTR+3
 FINISH 
 A(RPPTR)=CONTROLRP
 A(RPPTR+1)=FP
 RPPTR=RPPTR+3
 A(RPPTR)=15; ! ADD STEP TO CONTROL
 RPPTR=RPPTR+3
!
 IF NSE=0 START 
 A(RPPTR)=FORPTYPE<<16!2
 A(RPPTR+1)=FP
 A(RPPTR+2)=TAGS(FORNAME)
 A(RPPTR+3)=31; ! ASSIGN INCREMENT CONTROL
 RPPTR=RPPTR+6
 FINISH 
!
 A(RPPTR)=100
 RPPTR=RPPTR+3
 EXPOP(RR,ACCR,NOPS,FORTYPE)
 FINISH 
 RPPTR=RR
 ENTER JUMP(15,QQ,0)
 ENTER LAB(FEXITPL,B'111',LEVEL)
 P=PP; RETURN 
CPIB: ! CAN USE CPIB OR EQIVALENT
 PP=P+7; CPI=1
 A(RRR)=STEPRP; A(RRR+1)=STEPTMP
 A(RRR+3)=16; ! SUBTRACT
 A(RRR+6)=100
 EXPOP(RR,BREG,NOPS,FORTYPE); ! (INIT-STEP) TO BREG
!
 ACCESS=FINACC; AREA=FINAREA
 BASE=FINBASE
 ENTER LAB(QQ,0,LEVEL)
 IF STEPVAL=1 START 
 PSORLF1(CPIB,ACCESS,AREA CODE,FINDISP)
 IF STEPVAL>=0 THEN MASK=10 ELSE MASK=12
 FINISH ELSE START 
 PSF1(ADB,0,STEPVAL)
 PSORLF1(CPB,ACCESS,AREA CODE,FINDISP)
 IF STEPVAL>=0 THEN MASK=2 ELSE MASK=4
 FINISH 
!
! BEWARE OF ESCAPE DESCRIPTORS SINCE THESE ARE ALLOWED FOR FINAL VALUE
! DELETE THE NEXT STATEMENT WHEN 'STXN' ARRIVES AND ESCAPES ARE TRANSPARENT
!
 IF FINACC#0 THEN GRUSE(XNB)=0; ! MAY HAVE BEEN CORRUPTED
 GRUSE(BREG)=0
 COPY TAG(FORNAME)
 ACCESS=0; AREA=-1; BASE=I
 PSORLF1(STB,ACCESS,AREA CODE,K)
 NOTE ASSMENT(BREG,FORNAME)
 ENTER JUMP(MASK,FEXITPL,B'10')
 P=PP; ->COMM
FALTNO(2): ! WHILE <BE>
 ENTER LAB(QQ,0,LEVEL)
 A(RPPTR)=100
 RPPTR=RPPTR+3
 PP=P; EXPOP(RR,-1,NOPS,FORTYPE!16)
 RPPTR=RR
 P=PP; CCOND
 ENTER JUMP(MASK,FEXITPL,B'11')
 INTO FOR
 ENTER JUMP(15,QQ,0); ! UNCONDITIONALLY TO WHILE
 ENTER LAB(FEXITPL,B'111',LEVEL); ! TO EXIT WHEN BE FALSE
 RETURN 
FALTNO(3): ! NULL
 PP=P
 A(RPPTR)=100
 RPPTR=RPPTR+3
 EXPOP(RR,-1,NOPS,FORTYPE!16)
 P=PP; RPPTR=RR
 INTO FOR
END 
ROUTINE INTOFOR
INTEGER I
 IF FORLISTE#2 THEN START 
 ENTERJUMP(0,FPL,0)
 IF INCLUDE HANDCODE=NO THEN START 
 CYCLE I=0,1,7
 GRUSE(I)=0
 REPEAT 
 FINISH ELSE START 
 *LSQ_0
 *LCT_GRUSE+4
 *ST_(CTB +0)
 *ST_(CTB +4)
 FINISH 
 FINISH ELSE START 
 P=P+1
 C FOR BODY
 FINISH 
END 
ROUTINE C FORBODY
!***********************************************************************
!* A FOR BODY IS NORMALLY ENTERED BY A JLK *
!***********************************************************************
INTEGER FBALT,I,PL,RAD
 IF FORLISTE#2 THEN START 
 PLABEL=PLABEL-1; PL=PLABEL
 ENTER JUMP(15,PL,B'10')
 ENTER LAB(FPL,0,LEVEL)
 RAD=N; N=RAD+4
 PLANT(X'6398'); ! LSS TOS GET RETURN ADDRESS
 PSF1(ST,1,RAD); ! AND SAVE IN STACK FRAME
 FINISH 
 PTYPE=-3; I=P
 RHEAD(-1)
 AUXSBASE(LEVEL)=AUXSBASE(LEVEL-1)
 COLABEL
 FBALT=A(P); P=P+1
 IF FBALT=1 THEN START ; ! %BEGIN
 CBLK(-2)
 IF A(P)=1 THEN FAULT(47,0)
 FINISH ELSE START 
 CSTMNT
 FINISH 
 CEND(FLAG(LEVEL))
 IF FORLISTE#2 THEN START 
 PSF1(JUNC,1,RAD)
 ENTER LAB(PL,B'111',LEVEL)
 FINISH 
END 
END 
 ROUTINE CSTMNT
!***********************************************************************
!* COMPILE AN ALGOL STATEMENT WHICH CAN BE A DUMMY *
!***********************************************************************
 SWITCH ALT,UALT(1:4)
INTEGER SALT,PL1,PL2,CORB,PP,LNAM,CURRLINE
 CURRLINE=LINE
 PP=P
 ->ALT(A(P))
ALT(1): ! UI
 P=P+1; CUI
 RETURN 
ALT(2): ! FOR STMNT
 C FOR STMNT
 RETURN 
ALT(3): ! %IF <BE> %THEN ...
 P=P+1; CCOND
 PLABEL=PLABEL-1; PL1=PLABEL
!
! A SIMPLE PIECE OF OPTIMISATION IS TO AVOID JUMPING ROUND A ONE-
! INSTRUCTION JUMP WHICH OCCURS WHEN THE STATEMENT TURNS OUT TO BE A
! UNLABELLED 'GOTO' TO A LABEL IN THE CURRENT BLOCK
!
 IF A(P)=2 AND A(P+1)=3 AND A(P+2)=3 AND A(P+3)=2 AND C 
 A(P+4)=1 AND A(P+6)=3 START 
 LNAM=A(P+5); COPY TAG(LNAM)
 IF PTYPE=6 AND OLDI=LEVEL THEN START 
 ENTER JUMP(REVERSE(MASK),LNAM,0)
 P=P+7
 IF A(P)#1 THEN RETURN 
 PL2=PL1; ->UON
 FINISH 
 FINISH 
!
! END OF A SIMPLE PIECE OF OPTIMISATION WHICH WILL NOT CATCH JUMPS OUT
! OF FOR LOOPS BUT SHOULD CATCH ALL OTHHER 1 INSTRUCTION GOTOS
!
 ENTER JUMP(MASK,PL1,B'10'); ! MERGE NOT SHORT
 COLABEL; SALT=A(P); P=P+1
 ->UALT(SALT)
UALT(1): ! BEGIN
 CORB=A(P); P=P+1
 IF CORB=1 THEN CCMPNDSTMNT ELSE CBLK(-2)
 ->UBACK
UALT(2): ! FOR STMNT
 P=P-1
 C FOR STMNT; ->UBACK
UALT(3): ! UI
 CUI; ->UBACK
UALT(4): ! NULL
UBACK:
 IF A(P)#1 THEN C 
 ENTER LAB(PL1,B'11',LEVEL) AND RETURN ; ! MERGE
 IF SALT=2 THEN FAULT(47,0); ! %ELSE AFTER %FOR
 PLABEL=PLABEL-1; PL2=PLABEL
 ENTER JUMP(15,PL2,B'10')
 ENTER LAB(PL1,B'111',LEVEL); ! REPLACE
UON: LINE=A(P+1); P=P+2; COLABEL
 SALT=A(P); P=P+1
 SET LINE IF PARM LINE#0 AND LINE#CURR LINE
 IF SALT#1 THEN CSTMNT ELSE START 
 CORB=A(P); P=P+1
 IF CORB=1 THEN CCMPNDSTMNT ELSE CBLK(-1)
 FINISH 
 ENTER LAB(PL2,B'11',LEVEL); ! MERGE
 RETURN 
ALT(4): ! DUMMY STATEMENT
 WARN(4,0)
 END 
 ROUTINE CUI
!***********************************************************************
!* COMPILE AN UNCONDITIONAL STATEMENT *
!***********************************************************************
SWITCH ALT(1:3)
INTEGER OPHEAD,NOPS,BOT,TYPEP,LPALT,LPNAM,STOREOP,JJ,KK,LP,RR
RECORDNAME LCELL(LISTF)
 ->ALT(A(P))
ALT(1): ! ASSIGNMENT
 RR=RPPTR; NOPS=0
 LPNAM=A(P+1)
 TCELL=TAGS(LPNAM)
 LCELL==ASLIST(TCELL)
 TYPEP=LCELL_S1>>16&7
 STOREOP=31; ! ALLOW MVC ON SINGLE LPLS
 LPALT=A(P+2)
 IF (LPALT=1 AND TYPEP#3) OR (LPALT=2 AND TYPEP>=3) START 
 IF LPALT=1 THEN FAULT(24,A(P+1)) ELSE FAULT(42,A(P+1))
 TYPEP=4-LPALT
 FINISH 
!
! SHIFT THE ENTRY FOR P<NAME> UP ONE PLACE TO OVERWRITE THE ALT OF P<ASS>
! SO THAT IT IS NEXT TO P<APP> FOR CNAME ETC AND THE FIRST DESTINATION
! IN LEFT PART LIST CAN THEN BE TREATED AS ANY SUBSEQUENT ENTRY
!
 A(P+2)=A(P+1); P=P+2
 ->ON
AGN: LPNAM=A(P)
 TCELL=TAGS(LPNAM)
 LCELL==ASLIST(TCELL)
ON: BOT=RPPTR
 PTYPE=LCELL_S1>>16
 FAULT(29,LPNAM) UNLESS PTYPE&7=TYPEP
 IF PTYPE&X'F0'#0 THEN START 
 CNAME(1,ACCR)
 IF A(P)=1 THEN START ; ! MORE LPL FOLLOWS
 JJ=TAGS(A(P+1))
 IF ASLIST(JJ)_S1&X'F0000F'=X'200001' START 
 A(RPPTR)=X'51'<<16!BREG<<12!9
 REGISTER(BREG)=1
 OLINK(BREG)=ADDR(A(RPPTR))
 FINISH ELSE START 
 PLANT(X'5B98'); ! STB TOS STACK SUBSCRIPT
 A(RPPTR)=X'51'<<16!TOS<<12!8
 FINISH 
 A(RPPTR+1)=0
 FINISH ELSE START 
 GET WSP(KK,1); ! LOCAL TEMPORARY
 A(RPPTR)=X'51'<<16!BREG<<12!9
 A(RPPTR+1)=KK
 REGISTER(BREG)=2
 OLINK(BREG)=ADDR(A(RPPTR))
 FINISH 
 A(RPPTR+3)=32
 A(RPPTR+4)=LPNAM
 RPPTR=RPPTR+6
 FINISH ELSE START 
 JJ=PTYPE<<16!2; KK=P
 IF PTYPE&X'F000'#0 START 
 I=LCELL_S1>>4&15
 CYCLE LP=LEVEL,-1,1
 IF WRD(LPNAM)=M(LP) START 
 JJ=(PTYPE&7)<<16!(I+1)<<8!6
 KK=SET(I+1)>>18; EXIT 
 FINISH 
 REPEAT 
 IF LP<=1 OR A(P+1)#3 THEN FAULT(29,LPNAM)
 FINISH 
 A(RPPTR)=JJ
 A(RPPTR+1)=KK
 A(RPPTR+2)=TCELL
 A(RPPTR+3)=STOREOP
 A(RPPTR+4)=A(P)
 RPPTR=RPPTR+6
 P=P+1; IF A(P)=3 THEN P=P+1 ELSE SKIP APP
 FINISH 
 IF STOREOP=30 THEN JJ=99 ELSE JJ=100
 A(RPPTR)=JJ
 A(RPPTR+1)=BOT-9
 RPPTR=RPPTR+3
 STOREOP=30; NOPS=NOPS+1
 IF A(P)=1 THEN P=P+1 AND ->AGN
 P=P+1
 ETORP(OPHEAD,NOPS,TYPEP)
 A(RPPTR-3)=99
 A(RPPTR-2)=BOT; ! TIC BACK TO LEFTPART LIST
 ! WHICH IS BACK LINKED
 ! SO THAT ASSIGNMENTS ARE MADE
 ! R TO L AS SUBCRIPTS UNSTACKED
 LP=P
 EXPOP(OPHEAD,-1,NOPS,TYPEP!16)
 P=LP
 RPPTR=RR
 RETURN 
ALT(2): ! PROCEDURE CALL
 P=P+1
 CNAME(0,0)
 RETURN 
ALT(3): ! %GOTO <DE>
 P=P+1
 CDE(0)
 END 
ROUTINE GOTOLAB(INTEGER MODE)
!***********************************************************************
!* GOTO A SIMPLE LAB OR ELEMENT OF SWITCH UNCONDITIONALLY *
!* MODE =0 NORMAL GOTO STMNT *
!* MODE=1 IF IN THUNKS (IE LABEL PASSED BY NAME) *
!* MODE=2 IF IN SWITCH LIST (FAILURES HANDLED DIFFERENTLY) *
!* MODE=3 SWITCH BEING PASSED BY NAME *
!* MODE=5 AS MODE=1 BUT P<DE> HAS BEEN PARSED AS AN EXPRSN *
!* THIS IS UNAVOIDABLE IN THE CASE OF ACTUAL PARAMETERS AS *
!* BOTH LABELS AND PARAMETERLESS PROCEDURE CAN BE USED *
!* WITHOUT BEING DECLARED! *
!***********************************************************************
ROUTINESPEC RESET STACK
INTEGER LNAM, SB, B, D, PP, F, SSN, RANGE, ARRP, LEVELP, XYNB
 LNAM=A(P); P=P+1; ! LNAM =LABEL(SWITCH)NAME
 PP=P
 COPYTAG(LNAM)
 RANGE=KFORM; ARRP=ARR; LEVELP=OLDI
 B=I; D=K
 SSN=SNDISP<<2
 IF A(P)=2 THEN F=22 AND ->ERROR
 IF ARRP>=1 AND MODE#3 AND A(P)=3 THEN F=18 AND ->ERROR
 IF TYPE#6 OR ROUT=1 THEN F=11 AND ->ERROR
 SB=STACKBASE(B)
 ->SWITCH IF ARRP>=1; ! SWITCHES
 ABORT IF SB<0 AND B#RLEVEL AND NAM=0
!
 IF A(P)=1 THEN F=4 AND ->ERROR
 P=P+1
 IF NAM=1 THEN START ; ! LABEL BY NAME
 CALL THUNKS(0, -1, B, D)
 RETURN 
 FINISH 
!
 RESET STACK
!
 ENTER JUMP(15, LNAM, 0)
 RETURN 
ERROR: FAULT(F,LNAM)
 P=PP; SKIP APP;
 RETURN 
!
SWITCH: ! GOTO SWITCH
 P=P+1
 P=P+1 UNLESS MODE=3; ! PAST (HOLE) IN P(APP)
 IF NAM=1 THEN START 
 CSEXP(ACCR, 1, 0) UNLESS MODE=3
 CALL THUNKS(0, -1, B, D); ! CAN NOT RETURN
 FINISH ELSE START 
 IF MODE#3 THEN CSEXP(BREG, 1, 0) ELSE PLANT(X'499C');! ST BREG
 REGISTER(BREG)=1
 XYNB=SET XORYNB(-1,-1)
 PLANT(X'2201'); ! SBB 1 ALGOL SWITCHES START AT 1
 IF ARRP=2 START 
 RESET STACK
!
! FOLLOWING 3 LINES AVOID H-W BUG ON 50&60 RE JUMP TO CODE DECSCRPTR
! WHEN FIXED DELETE 3 LINES AND UNCOMMENT NEXT 2 LINES
!
 ->NOT 2960
 PLANT(X'2A04'); ! MYB 4
 PF1(ADB,0,XYNB,SSN+4); ! RELOCATE FROM CODE DEC
 PLANT(X'1B9C'); ! J BREG
NOT 2960: ! END OF REPABLE ALT
 PLANT(X'2A02'); ! MYB 2
 PF1(JUNC,3,XYNB,SSN); ! USE BOUNDED CODE DESCRIPOR
 FINISH ELSE START 
 PF1(LB,3,XYNB,SSN); ! LB REL DISP OF SW ELMNT
 PF1(ADB,0,XYNB,SSN+4); ! RELOCATE
!
! MUST SET LNB TO EXPECTED VALUE BEFORE BRANCHING INTO THE SWITCH
! CODE.
!
 IF B#RLEVEL THEN PSF1(LLN,1,PTR OFFSET(B))
 PLANT(X'1B9C'); ! JUNC BREG
 FINISH 
 REGISTER(BREG)=0; GRUSE(BREG)=0
 FINISH 
 IF MODE#3 THEN START 
 IF A(P)=1 THEN F=18 AND ->ERROR
 P=P+1
 FINISH 
 RETURN 
ROUTINE RESET STACK
INTEGER I
!
! IF JUMPING OUT OF A BLOCK IT MAY BE NECESSARY TO RESET BLOCK NO
! AND/OR THE TOP OF STACK POINTER
!
 IF PARMTRCE=0 OR B#RLEVEL OR LEVELP=LEVEL THEN ->NEXT
!
! IT IS STILL NOT NECESSARY TO RESET DIAG POINTER IF THE ONLY BLOCKS
! BEING LEFT ARE THE HYPOTHETICAL BLOCKS SURROUNDING FOR STMNTS
!
 CYCLE I=LEVEL,-1,LEVELP+1
 ->RESET IF FLAG(I)#-3; ! ANYTHING BUT FOR LOOP
 REPEAT 
 ->NEXT
RESET:
 PLANT(X'7883'); ! LD LNB+12 - PLT DECRIPTOR
 GRUSE(DR)=0
 DIAG POINTER(LEVELP)
!
NEXT:
 DISP=AUXSBASE(LEVELP)
!
! CASE DISP=0 OCCURSS WHEN THERE IS NO AUXSTACK REQD AT ALL !
! SIMILARLY THE CASE OF SB<=0 IF NO BLOCKS TO BE EXITED FROM
!
 IF DISP#0 AND (DISP#AUXSBASE(LEVEL) OR MODE#0) START 
 AREA=-1; BASE=DISP>>18
 DISP=DISP&X'3FFFF'
 GET IN ACC(ACCR,1,0,AREA CODE,DISP+12)
 PSORLF1(ST,2,AREA,DISP)
 FINISH 
!
 IF SB>0 AND (B#RLEVEL OR MODE#0) START ;! AUTO STACK NEEDS RESETTING
 PSF1(LLN,1,PTR OFFSET(B)) UNLESS B=RLEVEL
 PSF1(LSS,1,SB)
 PPJ(0,4)
 FINISH 
END 
END 
ROUTINE CSDE(INTEGER MODE)
!***********************************************************************
!* COMPILE A SIMPLE DESIGNATIONAL EXPRESSION *
!* P<SDE>:=<NAME><LABAPP>,'('<DE>')' *
!* MODE AS FOR ROUTINE GOTOLAB *
!***********************************************************************
INTEGER PP,PLUSALT,OPALT
 PP=P; P=P+1
 IF MODE#5 THEN START 
 IF A(PP)=2 THEN CDE(MODE) ELSE GOTOLAB(MODE)
 FINISH ELSE START 
 PLUSALT=A(P); OPALT=A(P+1)
 ->ERROR UNLESS PLUSALT=3 AND OPALT#2;! NOT INTEGER CONSTANT
 P=P+2; ! POINTS TO OPERAND
 IF OPALT=3 THEN CDE(5) ELSE GOTOLAB(5)
 ->ERROR UNLESS A(P)=2; ! NO REST OF EXPRN
 P=P+1
 FINISH 
 RETURN 
ERROR: FAULT(5,0)
 P=PP; SKIP EXP(0)
END 
ROUTINE CDE(INTEGER MODE)
!***********************************************************************
!* COMPILE A DESIGNATIONAL EXPRSSION *
!* P<DE>:-%IF<BEXP>%THEN<SDE>%ELSE<DE>,<SDE> *
!* MODE AS FOR ROUTINE GOTOLAB *
!***********************************************************************
INTEGER R, PL1, PL2
 IF A(P)=2 THEN P=P+1 AND CSDE(MODE) AND RETURN 
 P=P+1; CCOND
 PLABEL=PLABEL-1; PL1=PLABEL
 ENTER JUMP(MASK, PL1, B'11'); ! ROUND FIRST SDE ON FALSE
 R=0; CSDE(MODE)
 PLABEL=PLABEL-1; PL2=PLABEL
 IF R#0 THEN ENTER JUMP(15, PL2, B'11')
 ENTER LAB(PL1, B'110',LEVEL); ! UNCONDITIONAL AND REPLACE
 CDE(MODE)
 ENTER LAB(PL2, B'11',LEVEL); ! CONDITIONAL AND MERGE
END 
ROUTINE CCOND
!***********************************************************************
!* COMPILES A CONDITION INDEXED BY P AND LEAVES MASK SET UP *
!* READY FOR A BRANCH IF FALSE OPERATION *
!***********************************************************************
INTEGER PP, EXPHEAD, NOPS, RR
 RR=RPPTR; NOPS=0
 ETORP(EXPHEAD,NOPS,4)
 PP=P
 EXPOP(EXPHEAD,ACCR,NOPS,3)
 P=PP
 IF NEST>=0 THEN MASK=20
 RPPTR=RR
END 
ROUTINE CSEXP(INTEGER REG, MODE, NME)
!***********************************************************************
!* COMPILE A SIGNED EXPRESSION TO REGISTER 'REG' IN MODE 'MODE' *
!* MODE=1 FOR %INTEGER, =2 REAL, =3 BOOL *
!* NME=2 IF EXPRESSION IS A SINGLE NAME, #2 FOR GENUINE EXPRSN *
!***********************************************************************
INTEGER EXPHEAD, NOPS, PP, RR, ENAME, T
 RR=RPPTR
 IF NME=2 THEN START ; ! EXPRSN (PARAM)IS NAME APP
 ENAME=A(P)
 T=TAGS(ENAME)
 PTYPE=ASLIST(T)_S1>>16
 IF PTYPE&7=MODE THEN CNAME(2,REG) AND RETURN 
 IF PTYPE=SNPT THEN REDUCE TAG ELSE TYPE=PTYPE&7
 IF MODE=3 AND TYPE#3 THEN FAULT(24, ENAME)
 IF MODE<3 AND TYPE=3 THEN FAULT(42, ENAME)
 EXPHEAD=RPPTR
 A(RPPTR)=PTYPE<<16!2
 A(RPPTR+1)=P
 A(RPPTR+3)=100
 RPPTR=RPPTR+6
 NOPS=1
 FINISH ELSE START 
 NOPS=0
 ETORP(EXPHEAD, NOPS, MODE)
 FINISH 
 PP=P
 EXPOP(EXPHEAD, REG, NOPS, MODE)
 P=PP
 RPPTR=RR
END 
ROUTINE ETORP(INTEGERNAME HEAD, NOPS, INTEGER MODE)
!***********************************************************************
!* CONVERT EXPRESSION TO REVERSE POLISH *
!***********************************************************************
INTEGER TYPEP, TMODE, BHEAD, EHEAD1, EHEAD2, RR
! ABORT %UNLESS 1<=A(P)<=2
 IF A(P)=2 THEN START 
 P=P+1
 TORP(HEAD,NOPS,MODE)
 FINISH ELSE START 
 P=P+1
 RR=RPPTR; HEAD=RR; RPPTR=RPPTR+3
 IF MODE>=3 THEN TMODE=3 ELSE TMODE=0
 ETORP(BHEAD,NOPS,4)
 TORP(EHEAD1,NOPS,TMODE)
 TYPEP=PTYPE; EHEAD2=0
 ETORP(EHEAD2,NOPS,TMODE)
 PTYPE=2 UNLESS TYPEP=1
 IF TMODE=3 THEN PTYPE=3
 A(RR)=99
 A(RR+1)=RPPTR
 A(RPPTR)=PTYPE<<16!4
 A(RPPTR+1)=(BHEAD-RPBASE)<<16!(EHEAD1-RPBASE)
 A(RPPTR+2)=EHEAD2
 A(RPPTR+3)=100
 RPPTR=RPPTR+6
 NOPS=NOPS!X'80000000' ;! SOMETHING NASTY BIT SET
 FINISH 
END 
ROUTINE TORP(INTEGERNAME HEAD, NOPS, INTEGER MODE)
!***********************************************************************
!* CONVERT THE SIGNED EXPRESSION INDEXED BY P INTO REVERSE *
!* POLISH NOTATION. THE REVERSE POLISH LIST IS ADDED TO 'HEAD' *
!* WHICH MAY CONTAIN ANOTHER EXPRESSION. THE NUMBER OF OPERATORS *
!* IS ADDED TO NOPS. MODE SIGNIFIES :- *
!* MODE=1 INTEGER EXPRESSION *
!* MODE=2 REAL EXPRESSION *
!* MODE=3 BOOLEAN EXPRESSION *
!* MODE=4 A COMPARISION *
!* MODE=0 INTEGER IF POSIIBLE OTHERWISE REAL *
!* N.B. AN INTEGER EXPRESSION IS A SPECIAL CASE OF A REAL EXPRSN *
!***********************************************************************
SWITCH OPERAND(1:12)
INTEGER RPHEAD, PASSHEAD, SAVEHEAD, RPBOT, PASSBOT, SAVEBOT, C 
 REAL, BOOL, OPSEEN, COMPLEX, OPERATOR, OPPREC, OPND, C, D, C 
 PP, RPTYPE, RPINF, XTRA, OPMASK, OPSTK, OPPSTK
CONSTINTEGERARRAY OPINF(1:13)=X'519'(2),X'30F',
 X'310',X'413',X'415',X'414',
 X'519',X'416',X'312',X'217',X'111'(2)
! OPINF IS THE PRECEDENCE<<8!EXPOP SWITCH VALUE OF ALT OF P<OP>
 OPSTK=0; OPPSTK=0; PASSHEAD=0; RPHEAD=0; OPSEEN=0
 SAVEHEAD=0; REAL=0; OPMASK=0; BOOL=0
 RPBOT=0; SAVEBOT=0; PASSBOT=0
 PP=P; HEAD=RPPTR
 IF MODE=3 OR MODE=4 THEN BOOL=8
NEXTB: P=P+1; ! PAST HOLE
 C=A(P)
 IF 2=C AND BOOL=0 THEN START ;! INITIAL '-'
 OPMASK=1<<21
 NOPS=NOPS+1; OPSEEN=1
 OPSTK=11; OPPSTK=3
 FINISH 
 IF BOOL#0 AND C=1 START 
 OPMASK=OPMASK!1<<22
 NOPS=NOPS+1; OPSEEN=1
 WHILE 5<=OPPSTK&31 CYCLE 
 A(RPPTR)=OPSTK&31
 RPPTR=RPPTR+3
 OPSTK=OPSTK>>5; OPPSTK=OPPSTK>>5
 REPEAT 
 OPSTK=OPSTK<<5!10; OPPSTK=OPPSTK<<5!5
 FINISH 
NEXTOPND: OPND=A(P+1); P=P+2
 COMPLEX=0; XTRA=0
 ->OPERAND(BOOL+OPND); ! SWITCH ON OPERAND
OPERAND(1): ! NAME
OPERAND(10): ! BOOLEAN NAME
 C=A(P)
 D=TAGS(C); PTYPE=ASLIST(D)_S1>>16
 IF PTYPE=X'FFFF' THEN PTYPE=7; ! NAME NOT SET GIVES X'FFFF'
 IF PTYPE=SNPT THEN PTYPE=X'1000'+TSNAME(ASLIST(D)_S3>>16)
 TYPE=PTYPE&7
 IF PTYPE&X'FFF0'#0 OR PARMCHK=1 THEN COMPLEX=1
 IF PTYPE&X'F000'#0 THEN OPMASK=OPMASK!X'80000000'
 ! SET SOMETHING NASTY BIT FOR RTS
 IF ADFLAG#0 START 
 REDUCE TAG
 IF OLDI=LEVEL AND SNDISP#M'FP' THEN FAULT(27,C)
 FINISH 
 IF TYPE=2 THEN REAL=1
 RPTYPE=2; RPINF=P
 IF BOOL=0 THEN START 
 IF PTYPE=7 THEN PTYPE=1 AND UNPACK
 IF TYPE>=3 THEN START 
 FAULT(42,C)
 RPTYPE=0; PTYPE=1
 FINISH 
 FINISH ELSE START 
 IF PTYPE=7 THEN PTYPE=3 AND UNPACK
 IF TYPE#3 THEN START 
 FAULT(24,C)
 RPTYPE=0; PTYPE=3
 FINISH 
 FINISH 
 P=P+1
 IF A(P)=3 THEN P=P+1 ELSE SKIP APP; P=P+1
INS: A(RPPTR)=PTYPE<<16!COMPLEX<<8!RPTYPE
 A(RPPTR+1)=RPINF
 A(RPPTR+2)=XTRA
 RPPTR=RPPTR+3
 ->OP
OPERAND(2): ! CONSTANT
 C=A(P); RPTYPE=1
 IF C=2 THEN START ; ! REAL CONSTANT
 PTYPE=2;
 RPINF=A(P+1)
 XTRA=A(P+2)
 P=P+4
 REAL=1
 FINISH ELSE START 
 D=A(P+1)
 IF D>>17=0 THEN RPTYPE=0
 RPINF=D
 P=P+3; PTYPE=1
 FINISH ; ->INS
OPERAND(9): ! (EXPR)(COMP)(EXPR)
 ETORP(PASSHEAD,NOPS,0)
 RPPTR=RPPTR-3
 C=A(P); P=P+1
 IF C>7 THEN C=C-7; ! MAP ECMA FORM ONTO IMP FORM
 ETORP(SAVEHEAD,NOPS,0)
!
! OPTIMISE SIMPLE CONDITIONS HERE
!
 IF MODE=4 AND OPSEEN=0 AND A(P)=2 THEN D=27 ELSE D=26
 A(RPPTR-3)=D; A(RPPTR-2)=C; ! COMPARAISON & COMPARATOR
 P=P+1; ->OP
OPERAND(11): ! BOOLEAN CONSTANT
 C=A(P); P=P+2; ! 0=FALSE -1=TRUE
 PTYPE=3; RPTYPE=0
 RPINF=C-2; ->INS
OPERAND(3): ! SUB EXPRESSION
OPERAND(12): ! SUB EXPRESSION
 ETORP(PASSHEAD,NOPS,3*(BOOL>>3))
 RPPTR=RPPTR-3
 REAL=1 IF TYPE=2
 P=P+1
OP: ! DEAL WITH OPERATOR
 ->EOE IF A(P-1)=2; ! EXPR FINISHED
 OPERATOR=A(P)
!
 OPPREC=OPINF(OPERATOR+BOOL)
 OPERATOR=OPPREC&63
 IF OPERATOR=21 THEN REAL=1
 OPPREC=OPPREC>>8
 OPMASK=OPMASK!1<<(OPERATOR+5)
 NOPS=NOPS+1; OPSEEN=1
!
! UNLOAD THE OPERATOR STACK OF ALL OPERATORS WHOSE PRECEDENCE IS
! NOT LOWER THAN THE CURRENT OPERATOR. AN EMPTY STACK GIVES'-1'
! AS PRECEDENCE.
!
 WHILE OPPREC<=OPPSTK&31 CYCLE 
 A(RPPTR)=OPSTK&31
 RPPTR=RPPTR+3
 OPSTK=OPSTK>>5; OPPSTK=OPPSTK>>5
 REPEAT 
!
! THE CURRENT OPERATOR CAN NOW BE STORED
!
 OPSTK=OPSTK<<5!OPERATOR; OPPSTK=OPPSTK<<5!OPPREC
 ->NEXTOPND IF BOOL=0; ->NEXTB
EOE: ! END OF EXPRESSION
 WHILE OPSTK#0 CYCLE 
 A(RPPTR)=OPSTK&31
 RPPTR=RPPTR+3
 OPSTK=OPSTK>>5
 REPEAT 
 A(RPPTR)=100
 RPPTR=RPPTR+3
 IF BOOL#0 THEN PTYPE=3 ELSE PTYPE=1+REAL
 TYPE=PTYPE
 IF REAL=1 THEN OPMASK=OPMASK!1<<26;! REALS CANNOT BE EVALUATED IN B
 NOPS=NOPS!OPMASK
END 
ROUTINE EXPOP(INTEGER INHEAD, REG, NOPS, MODE)
!***********************************************************************
!* EVALUATE A LIST OF OPERAND AND'NOPS' OPERATORS AND LEAVE *
!* THE RESULT IN REG *
!* INHEAD HOLDS THE LIST THE BOTTOM BYTE OF STREAM 1 DEFINES THE *
!* ENTRY AS FOLLOWS:- *
!* 0 = SHORT (INTEGER) CONSTANT <18 BITS --S2=CONSTANT *
!* 1 = OTHER CONSTANT S2 (+S3 IF NEEDED) = CONSTANT *
!* 2 = VARIABLE S2 POINT TO AR ENTRY FOR NAME&SUBSCRIPTS *
!* (3 = DOPE VECTOR ITEM IF NEEDED) *
!* (4 = CONDITONAL EXPRESSION AS IN ALGOL) *
!* 7 = INTERMEDIATE RESULT UNDER LNB S2=DISPLCMNT FROM LNB *
!* 8 = INTERMEDIATE RESULT STACKED *
!* 9 = INTERMEDIATE RESULT IN A REGISTER S2 = REG *
!* *
!* 10-19 = UNARY OPERATOR S2=OP S3 =EXTRA *
!* 20 UP = BINARY OPERATOR *
!* *
!* ARRAY MCINST HOLD THE OPCODES CORRESPONDING TO THE OPERATORS:- *
!* TOP BYTE = REAL FORWARD FORM *
!* 2ND BYTE = REAL REVERSE FORM *
!* 3RD BYTE = INTEGER FORWARD FORM *
!* BTM BYTE = INTEGER REVERSE FORM *
!***********************************************************************
INTEGERARRAY OPERAND(1:2),STK(0:99)
RECORDNAME OPND1, OPND2, OPND3(RD)
RECORDNAME LCELL(LISTF)
INTEGER C, D, KK, JJ, OPCODE, COMM, XTRA, STPTR, RDFORM, EVALREG, C 
 PP, PT, JJJ, LOADREG
ROUTINESPEC FLOAT(RECORDNAME OPND)
ROUTINESPEC TYPE CHK(INTEGER MODE)
ROUTINESPEC FIX(RECORDNAME OPND,INTEGER MODE)
ROUTINESPEC CTOP(INTEGERNAME A)
ROUTINESPEC PUT
ROUTINESPEC STARSTAR
ROUTINESPEC REXP
ROUTINESPEC LOAD(RECORDNAME OPND,INTEGER REG, MODE)
CONSTINTEGERARRAY MCINST(10:32)=X'8E8E',X'F4F4E4E4',0(3),
 X'F0F0E0E0',X'F2F4E2E4',
 X'8E8E',X'8C8C',X'FAFAEAEA',
 X'AAAC',X'BABC0000',X'8A8A',
 X'8C00',0,X'FA00EA00',
 X'F6F6E6E6'(2),X'2C002C00',
 X'02000200',X'48004800'(3);
CONSTBYTEINTEGERARRAY FCOMP(1:28)=C 
 8,10,2,7,12,4,7,
 8,12,4,7,10,2,7,
 16,34,17,32,33,18,32,
 16,33,18,32,34,17,32;
SWITCH SW(10:32)
 STPTR=0; RDFORM=MODE&16
 EVALREG=ACCR
 IF REG=BREG AND NOPS&X'FEE00000'=0 THEN C 
 EVALREG=BREG
 IF REG=BREG#EVALREG AND REGISTER(BREG)>0 THEN BOOTOUT(BREG)
NEXT: C=A(INHEAD)
 XTRA=A(INHEAD+1)
 IF C=99 THEN INHEAD=XTRA AND ->NEXT; ! 99=TIC
 ->FINISH IF C=100
 JJ=C&255; D=INHEAD
 INHEAD=INHEAD+3
 ->OPERATOR IF 10<=JJ
!
! ANY OPERAND WHICH MAY NEED DR OR B OR ACC IN THEIR EVALUATION
! EG FUNCTIONS,ARRAY ELEMENTS ETC ARE FETCHED AND STACKKED FIRST
!
 OPND1==RECORD(ADDR(A(D)))
 IF (OPND1_FLAG=2 AND OPND1_XB#0) OR OPND1_FLAG=4 START 
 JJ=EVALREG
 IF JJ=BREG AND REGISTER(ACCR)=1 THEN JJ=ACCR
 LOAD(OPND1,JJ,0)
 FINISH 
 STK(STPTR)=ADDR(OPND1)
 STPTR=STPTR+1
! ABORT %IF STPTR>99
 ->NEXT
OPERATOR:
 STPTR=STPTR-1
 IF JJ>=15 THEN OPERAND(2)=STK(STPTR) AND STPTR=STPTR-1
 OPERAND(1)=STK(STPTR)
 OPCODE=MCINST(JJ)
 COMM=1
 OPND1==RECORD(OPERAND(1))
 OPND2==OPND1
 IF JJ>14 THEN START ; ! CHOOSE WHICH OPERAND FOR ACC
 OPND2==RECORD(OPERAND(2))
 IF OPCODE&X'00FF00FF'#0 THEN START 
 C=OPCODE
 IF OPND1_PTYPE&7=2 OR OPND2_PTYPE&7=2 THEN C=C>>16
 IF C>>8=0 OR (C&255#0 AND OPND2_FLAG=9) START 
 COMM=2; OPND3==OPND1
 OPND1==OPND2; OPND2==OPND3
 FINISH 
 FINISH 
 FINISH 
 IF OPND1_FLAG<2>OPND2_FLAG THEN CTOP(JJ)
 ->STRES IF JJ=0; ! CTOP CARRIED OUT
!
! CARRY OUT A TYPE CHECK FOR OPERATORS 15(+),16(-),19(*),COMP(26,27)
! AND ASSIGNMENT (30&31)
!
 IF OPND1_PTYPE&7#OPND2_PTYPE&7 AND C 
 (1<<JJ)&X'CC098000'#0 THEN TYPE CHK((JJ+2)>>5)
 ->SW(JJ)
SW(10): ! ¬
 LOAD(OPND1,EVALREG,2)
 PLANT(X'8E7F'); ! NEQ -1
 GRUSE(ACCR)=0
! ABORT %UNLESS EVALREG=ACCR
SUSE: OLINK(EVALREG)=OPERAND(COMM)
STRES: STK(STPTR)=OPERAND(COMM); STPTR=STPTR+1
 ->NEXT
SW(11): ! NEGATE
! OPMASK STOPS US EVER GETTING HERE WITH EVALREG=BREG (PDS HOPES)
 LOAD(OPND1,EVALREG,2)
 IF TYPE=2 THEN OPCODE=OPCODE>>16
 PSF1(OPCODE&255,0,0); ! IRSB 0 OR RRSB 0
 GRUSE(ACCR)=0
! ABORT %UNLESS EVALREG=ACCR
 ->SUSE
SW(12): !ENTER LAB
 LOAD(OPND1,EVALREG,2) IF XTRA>>16#0
 ENTERLAB(XTRA&X'FFFF',0,LEVEL)
 ->SUSE
SW(13): ! ENTIER
 IF OPND1_PTYPE&7=1 THEN FLOAT(OPND1)
 FIX(OPND1,XTRA); ->SUSE
SW(14): ! SIGN
 LOAD(OPND1,EVALREG,2)
 IF TYPE=2 THEN C=63 AND D=0 ELSE C=31 AND D=4
 PF3(JAT,D,0,5); ! SIGN(0)=0
 PSF1(USH,0,-C)
 PSF1(USH,0,1)
 PSF1(IRSB,0,1)
 GRUSE(ACCR)=0
 IF TYPE=2 THEN START 
 IF REGISTER(BREG)=0 THEN PLANT(X'4B9C') AND C 
 GRUSE(BREG)=0 ELSE PLANT(X'3211')
 ! 4B9C== STUH BREG
 ! 3211== MPSR 17
 FINISH 
 OPND1_PTYPE=1; OPND1_XB=ACCR<<4
 OPND1_FLAG=9; OPND1_D=0
! ABORT %UNLESS EVALREG=ACCR
 ->SUSE
SW(15): ! ADD
BINOP: LOAD(OPND1,EVALREG,2) UNLESS C 
 OPND1_FLAG=9 AND OPND1_XB>>4=EVALREG
 LOAD(OPND2,EVALREG,1) IF OPND2_FLAG<=4
 PUT; ->SUSE UNLESS JJ=17
 PLANT(X'8E7F'); ! NEQ -1
 ->SUSE
SW(16): ! SUBTRACT
 ->BINOP
SW(17): ! EXCLUSIVE OR
SW(18): ! OR
SW(22): ! AND
 ->BINOP IF OPND1_PTYPE&7=3=OPND2_PTYPE&7
 FAULT(24,0)
F25: JJ=15; OPCODE=MCINST(15); ->BINOP; ! CHANGE OPN TO +
F26: FAULT(26,0); ->F25
SW(23): ! %IMPLIES
 LOAD(OPND1,EVALREG,2)
 PLANT(X'8E7F'); ! NEQ -1
SW(24): ! SLL
SW(19): ! MULT
 ->BINOP
SW(20): ! INTEGER DIVISION
 ->F26 UNLESS OPND1_PTYPE&7=1=OPND2_PTYPE&7
 ->BINOP
SW(21): ! NORMAL DIVISION
 TYPE CHK(2); ->BINOP
SW(25): ! EXP
 IF OPND2_PTYPE&7=2 AND OPND1_PTYPE&7=1 THEN FLOAT(OPND1)
 IF OPND2_PTYPE&7=1 THEN STARSTAR AND ->SUSE
 REXP; COMM=2; ->SUSE
SW(26): ! COMPARISON TO BOOLEAN CONVERSION
SW(27): ! COMPARISONS 
 ->Z1 IF OPND1_FLAG<=1 AND OPND1_D=0 AND JJ=27
 ->Z2 IF OPND2_FLAG<=1 AND OPND2_D=0 AND JJ=27
 LOAD(OPND1,EVALREG,2)
 LOAD(OPND2,EVALREG,1)
 IF JJ=26 THEN START 
 PUT
 PLANT(X'6200'); ! LSS 0
 GRUSE(ACCR)=0; LOADREG=ACCR
 FINISH ELSE START 
 PUT; LOADREG=-1
 FINISH 
 MASK=REVERSE(FCOMP(XTRA+7*(COMM-1)))
 REGISTER(EVALREG)=0
 IF LOADREG=-1 THEN NEST=-1 AND RETURN 
 PF3(JCC,MASK,0,3)
 PLANT(X'627F'); ! LSS -1
 OPND1_PTYPE=3; OPND1_XB=ACCR<<4
 OPND1_FLAG=9; OPND1_D=0
 TYPE=3
 REGISTER(ACCR)=1
 ->SUSE
Z1: OPND3==OPND2; ->Z3
Z2: OPND3==OPND1
Z3: LOAD(OPND3,ACCR,2)
 MASK=REVERSE(FCOMP(XTRA+7*COMM+7))
 IF TYPE=1 THEN MASK=MASK+4
 NEST=-1; REGISTER(ACCR)=0
 RETURN 
SW(28): ! SPECIAL MH FOR ARRAY ACCESS
 C=OPND2_D>>16; ! CURRENT DIMENSION
 D=OPND2_D&31; ! TOTAL NO OF DIMENSIONS
 IF OPND1_FLAG=9 AND OPND1_XB>>4=ACCR THEN START 
 PLANT(X'4998'); ! ST TOS
 ! ACC CANNOT BE USED IN DVM
 CHANGE RD(ACCR)
 REGISTER(ACCR)=0
 FINISH 
!
 IF C=D THEN START ; ! TOP DIMENSION LOAD DV DES
 BASE=OPND2_XTRA>>18; AREA=-1
 GET IN ACC(DR,2,0,AREA CODE,OPND2_XTRA&X'1FFFF'+8)
 FINISH 
!
 LOAD(OPND1,EVALREG,0)
 AREA=OPND1_XB>>4; ACCESS=OPND1_XB&15
 IF C=D AND REGISTER(BREG)>=1 AND C 
 (OPND1_FLAG#9 OR AREA#BREG) THEN START 
 OPND3==RECORD(OLINK(BREG))
 OPND3_D=0
 REGISTER(BREG)=2
 BOOT OUT(BREG)
 FINISH 
!
! TWO DIMENSIONAL UNCHECKED ARRAYS AVOID VMY ON FIRST DIMENSION WHERE
! THEMULTIPLIER IS 1. THE AVOIDS HAVING TO COPY BTO ACC
!
 IF C=1 AND D=2 AND PARMARR=0 START 
 PLANT(X'23DC') UNLESS XTRA=2;! SBB (%DR) DR POINTS AT LB
 OPCODE=ADB<<8
 FINISH 
 ACCESS=OPND1_XB&15; AREA=OPND1_XB>>4
 PSORLF1(OPCODE>>8&255,ACCESS,AREA,OPND1_D)
 GRUSE(BREG)=0
!
 IF D=1 OR (D=2 AND PARMARR=0) THEN LOADREG=BREG C 
 ELSE START 
 LOADREG=ACCR
 IF C=D THEN GET IN ACC(ACCR,1,0,7,0) ELSE C 
 PLANT(X'E19C'); ! IAD BREG
 IF C=1 THEN START 
 PLANT(X'499C'); ! ST BREG
 REGISTER(ACCR)=0
 LOADREG=BREG
 FINISH 
 FINISH 
 REGISTER(LOADREG)=1
 OPND1_FLAG=9; OPND1_XB=LOADREG<<4
 OLINK(LOADREG)=OPERAND(COMM)
 IF C=1 THEN ->STRES
 ->NEXT
SW(29): ! ->LAB MASKS AND LAB AS OPND2
 ABORT
SW(30): ! ASSIGN(=)
SW(31): ! ASSIGN(WITH MVC ALLOWED)
 PP=OPND2_D; ! SAVE POINTER TO NAME
 PT=OPND2_PTYPE; ! AND ITS ORIGINAL PTYPE
 D=OPND2_FLAG; ! SAVE NAME OR R-DESCRPTOR
 LOAD(OPND1,ACCR,2) UNLESS OPND1_FLAG=9 AND OPND1_XB>>4=ACCR
 IF D=2 THEN START ; ! RHS= A NAME
 IF OPND2_PTYPE<=3 AND OPND2_UPTYPE=0 START 
 LCELL==ASLIST(OPND2_XTRA)
 D=LCELL_S3>>16
 AREA=-1; C=0
 BASE=LCELL_S1>>4&15
 IF BASE=RLEVEL THEN JJJ=LNB ELSE JJJ=AREA CODE
 FINISH ELSE START 
 P=PP; CNAME(1,0)
 D=DISP; C=ACCESS
 IF AREA<0 THEN AREA=AREA CODE;! ONLY NEEDED FOR BUM LHS
 JJJ=AREA
 FINISH 
 FINISH ELSE START ; ! LHS A FUNCTION DESIGNATOR
 IF D=6 START ; ! SPECIAL FLAG FOR FN RESULTS
 C=0
 BASE=OPND2_XB
 AREA=-1; JJJ=AREA CODE
 FINISH ELSE START ; ! ASSIGN TO TEMP (IN FORS)
 AREA=OPND2_XB>>4; JJJ=AREA
 ACCESS=OPND2_XB&15; C=ACCESS
 FINISH 
 D=PP
 FINISH 
 LOAD(OPND1,ACCR,2) UNLESS OPND1_FLAG=9
 PSORLF1(ST,C,JJJ,D)
 IF OPND2_FLAG=2 THEN NOTE ASSMENT(ACCR,A(PP)) ELSE C 
 SET USE(ACCR,10,XTRA); ! NOTE FN RESULT
 IF JJ=31 THEN REGISTER(EVALREG)=0
 COMM=1; ->SUSE
SW(32): ! ARRAY ASSNMT XTRA=ARRNAME
 C=TAGS(XTRA)
 LCELL==ASLIST(C)
 D=LCELL_S1; ! XTRA=LPNAME
 JJJ=D>>4&15; D=D>>16&15; ! D=TYPE : JJJ=I
 C=LCELL_S3>>16; ! C=K
 IF D=2 AND OPND1_PTYPE&7=1 THEN FLOAT(OPND1)
 IF D=1 AND OPND1_PTYPE&7=2 THEN FIX(OPND1,0)
 LOAD(OPND1,ACCR,2) UNLESS OPND1_FLAG=9 AND OPND1_XB>>4=ACCR;! RHS
 IF GRUSE(DR)=7 AND GRINF(DR)=XTRA START 
 IF 7<=OPND2_FLAG<=8 START 
 ACCESS=1
 IF OPND2_FLAG=7 THEN AREA=LNB AND DISP=OPND2_D C 
 ELSE AREA=TOS AND DISP=0
 FINISH ELSE START 
 LOAD(OPND2,BREG,2) C 
 UNLESS OPND2_FLAG=9 AND OPND2_XB>>4=BREG
 ACCESS=3; AREA=7; DISP=0
 FINISH 
 PF1(ST,ACCESS,AREA,DISP)
 FINISH ELSE START 
 LOAD(OPND2,BREG,2) C 
 UNLESS OPND2_FLAG=9 AND OPND2_XB>>4=BREG;! SUBSCRIPT EXP TO B
 AREA=-1; BASE=JJJ
 IF BASE=RLEVEL THEN AREA=LNB ELSE AREA=AREA CODE
 PF1(ST,3,AREA,C)
 FINISH 
 REGISTER(BREG)=0
 GRUSE(DR)=7; GRINF(DR)=XTRA
 COMM=1; ->STRES
FINISH:
 OPND1==RECORD(STK(STPTR-1))
 IF OPND1_PTYPE&7=1 AND MODE=2 THEN FLOAT(OPND1)
 IF OPND1_PTYPE&7=2 AND MODE=1 THEN FIX(OPND1,0)
 LOAD(OPND1,REG,2) UNLESS C 
 RDFORM#0 OR (OPND1_FLAG=9 AND OPND1_XB>>4=REG)
 PTYPE=OPND1_PTYPE
 TYPE=PTYPE&7
 NEST=-1
 IF OPND1_FLAG=9 THEN START 
 NEST=OPND1_XB>>4
 REGISTER(NEST)=0
 FINISH 
 RETURN 
!
ROUTINE LOAD(RECORDNAME OPND,INTEGER REG, MODE)
!***********************************************************************
!* LOAD OPERAND TO REGISTER CONDITIONALLY *
!* MODE=0 LEAVE IN STORE IF POSSIBLE *
!* MODE=1 LEAVE IN STORE IF SUITABLE FOR RX INSTRUCTIONS *
!* MODE=2 LOAD TO REGISTER REGARDLESS *
!***********************************************************************
INTEGER J, K, C, D, HEAD1, HEAD2
RECORDSPEC OPND(RD)
SWITCH SW(0:9)
 PTYPE=OPND_PTYPE; TYPE=PTYPE&7
 K=OPND_FLAG
 ->SW(K) IF MODE=2 OR 2<=K<=4 OR (K<2 AND MODE=1)
 RETURN 
SW(0):LITCONST: ! CONSTANT < 18 BITS
 AREA=0; ACCESS=0
 DISP=OPND_D
 IF MODE=2 THEN START ; ! FETCH TO REG
 IF GRUSE(REG)=5 AND GRINF(REG)=DISP AND TYPE=1 START 
 IF REGISTER(REG)#0 THEN BOOT OUT(REG)
 FINISH ELSE GETINACC(REG,BYTES(TYPE)>>2,ACCESS,AREA,DISP)
 IF TYPE=1 THEN GRUSE(REG)=5 AND GRINF(REG)=DISP
 ->LDED
 FINISH 
 OPND_FLAG=7; OPND_XB=AREA<<4!ACCESS
 OPND_D=DISP
 RETURN 
SW(1): ! LONG CONSTANT
 IF OPND_D=0=OPND_XTRA THEN ->LITCONST
 IF TYPE=1 AND IMOD(OPND_D)>>17=0 THEN ->LITCONST
 STORE CONST(DISP,BYTES(TYPE),OPND_D,OPND_XTRA)
 IF MODE#2 START 
 OPND_FLAG=7; AREA=PC; OPND_XB=AREA<<4
 ACCESS=0; OPND_D=DISP; RETURN 
 FINISH 
 IF GRUSE(REG)=6 AND GRINF(REG)=DISP START 
 IF REGISTER(REG)#0 THEN BOOT OUT(REG)
 FINISH ELSE GETINACC(REG,BYTES(TYPE)>>2,0,PC,DISP)
 GRUSE(REG)=6; GRINF(REG)=DISP
 ->LDED
SW(2): ! NAME
 P=OPND_D
 -> LOAD IF MODE=2 OR OPND_XB#0;! COMPLEX NAMES MUST BE LOADED
 CNAME(5,REG)
 ->LDED IF NEST>=0
 OPND_PTYPE=PTYPE
 OPND_FLAG=7
 OPND_XB=AREA<<4!ACCESS
 OPND_D=DISP; RETURN 
LOAD: CNAME(2,REG)
LDED: REGISTER(REG)=1; ! CLAIM THE REGISTER
 OLINK(REG)=ADDR(OPND)
 OPND_FLAG=9; OPND_D=0; OPND_XB=REG<<4; RETURN 
SW(4): ! CONDITIONAL EXPRSSN
 C=TYPE
 HEAD1=OPND_D>>16+RPBASE
 HEAD2=OPND_D&X'FFFF'+RPBASE
 SAVEIRS
 EXPOP(HEAD1,ACCR,2,3)
 IF NEST>=0 THEN MASK=20
 PLABEL=PLABEL-1; J=PLABEL
 ENTER JUMP(MASK,J,B'11')
 EXPOP(HEAD2,REG,2,C)
 IF REG>=0 THEN D=REG ELSE D=NEST
 PLABEL=PLABEL-1
 ENTER JUMP(15,PLABEL,B'11')
 HEAD1=OPND_XTRA
 ENTER LAB(J,B'111',LEVEL)
 J=PLABEL
 EXPOP(HEAD1,D,2,C)
 ENTER LAB(J,B'11',LEVEL)
 GRUSE(D)=0; OLINK(REG)=ADDR(OPND)
 OPND_PTYPE=C; REGISTER(D)=1
 OPND_FLAG=9; OPND_XB=REG<<4
 OPND_D=0; RETURN 
SW(6): ! SPECIAL FRIG FOR FN RESULTS
 ABORT; ! _XB = RLEVEL &_D =OFFSET
SW(7): ! I-R IN A STACK FRAME
 AREA=OPND_XB>>4
 ACCESS=OPND_XB&15
 DISP=OPND_D
PICKUP: GET IN ACC(REG,BYTES(TYPE)>>2,ACCESS,AREA,DISP)
 ->LDED
SW(8): ! I-R THAT HAS BEEN STACKED
 AREA=TOS; ACCESS=0; DISP=0; ->PICK UP
SW(9): ! I-R IN A REGISTER
 IF OPND_XB>>4=REG THEN ->LDED
 IF REG#ACCR THEN START 
 BOOTOUT(BREG) IF REGISTER(BREG)#0
 PLANT(X'499C'); ! ST BREG
 GRUSE(BREG)=GRUSE(ACCR)
 GRINF(BREG)=GRINF(ACCR)
 FINISH ELSE START 
 GET IN ACC(ACCR,1,0,7,0)
 GRUSE(ACCR)=GRUSE(BREG)
 GRINF(ACCR)=GRINF(BREG)
 FINISH 
 REGISTER(OPND_XB>>4)=0
 OPND_XB=REG<<4
 REGISTER(REG)=1
 OLINK(REG)=ADDR(OPND)
END 
ROUTINE PUT
!***********************************************************************
!* THIS ROUTINE PLANTS CODE TO PERFORM THE BASIC *
!* OPERATION DEFINED BY OPND1,OPND2 & OPCODE *
!***********************************************************************
INTEGER CODE
 CODE=OPCODE
 IF OPND2_PTYPE&7=2 THEN CODE=CODE>>16
 IF COMM=1 THEN CODE=CODE>>8
 CODE=CODE&255
 IF EVALREG=BREG THEN CODE=CODE-X'C0'
 AREA=OPND2_XB>>4
 ACCESS=OPND2_XB&15
 DISP=OPND2_D
 PSORLF1(CODE,ACCESS,AREA,DISP)
 GRUSE(EVALREG)=0 UNLESS JJ=27
 OLINK(EVALREG)=OPERAND(COMM)
 END 
ROUTINE CTOP(INTEGERNAME FLAG)
!***********************************************************************
!* THIS ROUTINE IS CALLED WHEN AN EXPRESSION OPERATION IS FOUND *
!* BETWEEN TWO CONSTANTS. SOME OPERATIONS ARE INTERPRETED *
!* ON EXIT FLAG=0 %IF OPERATION CARRIED OUT *
!***********************************************************************
INTEGER VAL1, VAL2, TYPEP, OP
LONGREAL RVAL1, RVAL2, X
SWITCH SW(10:28)
 OP=FLAG
 TYPEP=OPND1_PTYPE!OPND2_PTYPE
 RETURN IF OP>28 OR TYPEP>=3
 IF OPND1_PTYPE=2 THEN START 
 INTEGER(ADDR(RVAL1))=OPND1_D
 INTEGER(ADDR(RVAL1)+4)=OPND1_XTRA
 IF MOD(RVAL1)<IMAX THEN VAL1=INT(RVAL1)
 FINISH ELSE VAL1=OPND1_D AND RVAL1=VAL1
 IF OPND2_PTYPE=2 THEN START 
 INTEGER(ADDR(RVAL2))=OPND2_D
 INTEGER(ADDR(RVAL2)+4)=OPND2_XTRA
 IF MOD(RVAL2)<IMAX THEN VAL2=INT(RVAL2)
 FINISH ELSE VAL2=OPND2_D AND RVAL2=VAL2
 ->SW(OP)
INTEND:
 FLAG=0; OPND1_PTYPE=1
 IF 0<=VAL1<=4095 THEN OPND1_FLAG=0 ELSE OPND1_FLAG=1
 OPND1_D=VAL1
 RETURN 
SW(11): ! NEGATE
 IF TYPEP=1 THEN VAL1=-VAL1 AND ->INT END
 RVAL1=-RVAL1; ->REAL END
SW(13): ! ENTIER
 RETURN IF MOD(RVAL1)>IMAX; ! TOO BIG
 VAL1=INT(RVAL1); ->INT END
REAL END:
 OPND1_FLAG=1
 OPND1_D=INTEGER(ADDR(RVAL1))
 OPND1_XTRA=INTEGER(ADDR(RVAL1)+4)
 FLAG=0; OPND1_PTYPE=2
 RETURN 
SW(14): ! SIGN
 VAL1=0
 IF RVAL1>0 THEN VAL1=1
 IF RVAL1<0 THEN VAL1=-1
 ->INTEND
SW(15): ! ADD
 IF TYPEP=1 THEN VAL1=VAL1+VAL2 AND ->INT END
 RVAL1=RVAL1+RVAL2; ->REAL END
SW(16): ! MINUS
 IF TYPEP=1 THEN VAL1=VAL1-VAL2 AND ->INT END
 RVAL1=RVAL1-RVAL2; ->REAL END
SW(19): ! MULT
SW(28): ! ARRAY BOUND MULT
 IF TYPEP=1 THEN VAL1=VAL1*VAL2 AND ->INT END
 RVAL1=RVAL1*RVAL2; ->REAL END
SW(21): ! REAL DIVISION
 RETURN IF RVAL2=0; ! AVOID DIV BY ZERO
 RVAL1=RVAL1/RVAL2; ->REAL END
SW(20): ! '%DIV' DIVISION
 RETURN IF VAL2=0 OR TYPEP#1
 VAL1=VAL1//VAL2; ->INT END
SW(25): ! EXP
 RETURN IF RVAL1<=0
 IF TYPEP=1 AND 32>VAL2>0 THEN START 
 X=RVAL1**VAL2
 IF MOD(X)>IMAX THEN RETURN 
 VAL1=INT(X); ->INT END
 FINISH 
 IF OPND2_PTYPE=1 AND 63>IMOD(VAL2) C 
 THEN RVAL1=RVAL1**VAL2 AND ->REAL END
SW(10):
SW(12):
SW(17):
SW(18):
SW(22):
SW(23):
SW(24):
SW(26):
SW(27):
END 
ROUTINE FLOAT(RECORDNAME OPND1)
!***********************************************************************
!* PLANT CODE TO CONERT OPERAND1 FROM FIXED TO FLOATING *
!***********************************************************************
RECORDSPEC OPND1(RD)
 IF OPND1_FLAG<=1 THEN START 
 CVALUE=OPND1_D
 OPND1_D=INTEGER(ADDR(CVALUE))
 OPND1_XTRA=INTEGER(ADDR(CVALUE)+4)
 OPND1_FLAG=1
 FINISH ELSE START 
 LOAD(OPND1,ACCR,2)
 PLANT(X'A800'); ! FLT 0
 GRUSE(ACCR)=0
 FINISH 
 OPND1_PTYPE=2
 TYPE=2
END 
ROUTINE TYPE CHK(INTEGER MODE)
!***********************************************************************
!* MODE=0 ARITHMETIC := MAKE BOTH REAL UNLESS BOTH INTEGER *
!* MODE=1 ASSIGNMENT := FORCE OPERAND1 TO TYPE OF OPERAND 2 *
!* MODE=2 REAL DIVISION := MAKE BOTH REAL *
!***********************************************************************
INTEGER PT1,PT2
 PT1=OPND1_PTYPE&7
 PT2=OPND2_PTYPE&7
 IF MODE#2 AND PT1=1=PT2 THEN RETURN 
 IF MODE=1 THEN START 
 IF PT2=1 AND PT1=2 THEN FIX(OPND1,0) AND RETURN 
 FINISH ELSE START 
 IF PT2=1 THEN FLOAT(OPND2)
 FINISH 
 IF PT1=1 THEN FLOAT(OPND1)
END 
ROUTINE FIX(RECORDNAME OPND,INTEGER MODE)
!***********************************************************************
!* PLANT CODE TO CONVERT OPERAND TO FIXED POINT FORM *
!* CODE PLANTED IS AS FOR THE IMP ROUTINE 'INT' *
!* MODE =0 FOR ROUNDING *
!* MODE #0 FOR TRUNCATION *
!***********************************************************************
RECORDSPEC OPND(RD)
 IF OPND_FLAG=1 THEN START 
 INTEGER(ADDR(CVALUE))=OPND_D
 INTEGER(ADDR(CVALUE)+4)=OPND_XTRA
 IF MOD(CVALUE)<IMAX START 
 OPND_D=INT(CVALUE)
 TYPE=1; OPND_PTYPE=1
 RETURN 
 FINISH 
 FINISH 
 LOAD(OPND,ACCR,2); ! LOAD TO ANY FP REG
 IF REGISTER(BREG)#0 THEN BOOT OUT(BREG)
 IF MODE=0 THEN PF1(RAD,0,PC,SPECIAL CONSTS(0));! 0.5
! PSF1(RSC,0,55) %IF PARMOPT#0
! PSF1(RSC,0,-55) %IF PARMOPT#0
! PF1(X'B8',0,BREG,0)
! PSF1(MYB,0,4)
! PSF1(CPB,0,-64)
! PF3(JCC,10,0,3)
! PSF1(LB,0,-64)
! PF1(ISH,0,BREG,0)
! PF1(STUH,0,BREG,0)
 PCLOD(100-PARMOPT,103)
 GRUSE(ACCR)=0; GRUSE(BREG)=0
 OPND_PTYPE=1; TYPE=1
END 
ROUTINE STARSTAR
!***********************************************************************
!* PLANT IN-LINE CODE FOR EXPONENTIATION *
!***********************************************************************
INTEGER TYPEP,WORK,C,EXPWORK,VALUE
 PTYPE=OPND1_PTYPE; ! INSPECT THE OPERAND
 TYPE=PTYPE&7
 TYPEP=TYPE
 IF TYPEP=2 THEN OPCODE=OPCODE>>16
 OPCODE=(OPCODE>>8)&255
 VALUE=0
 IF OPND2_FLAG=0 AND 1<=OPND2_D<=63*TYPE THEN C 
 VALUE=OPND2_D; ! EXPONENT IS #0 AND CONSTANT
 LOAD(OPND1,ACCR,1); ! FETCH OPERAND TO ACC
!
! OPTIMISE **2 **3 AND **4
!
 IF 2<=VALUE<=4 THEN START 
 IF OPND1_FLAG=9 OR OPND1_XB&3#0 START 
 LOAD(OPND1,ACCR,2) UNLESS OPND1_FLAG=9
 PLANT(X'4998'); ! ST TOS
 IF VALUE=3 THEN PLANT(X'4998');! ST TOS
 PLANT(OPCODE<<8!X'198'); ! OPCODE TOS
 IF VALUE=4 THEN PLANT(X'4998');! ST TOS
 IF VALUE>2 THEN PLANT(OPCODE<<8!X'198');! OPCODE TOS
 FINISH ELSE START 
 GET IN ACC(ACCR,BYTES(TYPEP)>>2,ACCESS,AREA,DISP)
 CYCLE C=2,1,VALUE
 PSORLF1(OPCODE,ACCESS,AREA,DISP)
 REPEAT 
 OPND1_FLAG=9
 OPND1_XB=ACCR<<4
 OPND1_D=0
 REGISTER(ACCR)=1
 FINISH 
 GRUSE(ACCR)=0
 RETURN 
 FINISH ELSE LOAD(OPND1,ACCR,2)
!
! OTHERWISE STORE OPERAND IN 'WORK' AND GET HOLD OF EXPONENT
!
 GET WSP(WORK,BYTES(TYPE)>>2)
 IF TYPEP=2 THEN GET WSP(EXPWORK,1)
 PSF1(ST,1,WORK)
 PLABEL=PLABEL-1; ! LABEL FOR JUMPING OUT
 LOAD(OPND2,BREG,2); ! EXPONENT TO ANY REGISTER
 IF PARMOPT#0 THEN START 
 IF TYPEP=1 AND VALUE=0 THEN C 
 PPJ(30,7); ! J (B<0) TO ERROR ROUTINE
 PF3(JAT,13,0,4); ! J (B>0) ROUND NEXT JUMP
 PPJ(16,7); ! 0**0 IS ERROR IN ALGOL
 ! 0**(<0) GIVES DIVIDE ERROR
 FINISH 
 IF TYPEP=2 THEN PSF1(STB,1,EXPWORK)
!
! GET '1' INTO ACC IN APPROPIATE FORM
!
 IF TYPEP=1 THEN PLANT(X'6201') ELSE C 
 PF1(X'60',0,PC,SPECIAL CONSTS(1)); ! LD(E) WORK,=D'1'
!
! IF EXPONENT NOT KNOWN AT COMPILE TIME TO BE +VE CONSTANT MUST
! ALLOW FOR ZERO :- XX**0=1 FOR ALL XX
! ALSO ALLOW FOR X**(-N) WHICH IS 1/(X**N) FOR ALL X & N
!
 IF VALUE=0 THEN START ; ! NOT +VE CONSTANT
 ENTER JUMP(28,PLABEL,B'11');! J(B=0) END OF EXP ROUTINE
 IF TYPEP=2 THEN START 
 PF3(JAT,13,0,4); ! J*+4 IF B>0
 PLANT(X'5200'); ! SLB 0
 PLANT(X'2398'); ! SBB TOS
 FINISH 
 FINISH 
 C=CA
 PSF1(OPCODE,1,WORK)
 PSF1(DEBJ,0,(C-CA)//2)
!
! FOR REAL EXPONENTS CHECK IF NEGATIVE AND EVALUATE INVERSE
!
 IF VALUE=0 AND TYPEP=2 THEN START 
 PSF1(LB,1,EXPWORK); ! LB ON ORIGINAL EXPONENT
 ENTER JUMP(46,PLABEL,B'11');! BP END OF EXP ROUTINE
 PF1(RRDV,0,PC,SPECIAL CONSTS(1));! RRDV 1.0
 FINISH 
!
! ALL OVER. RESULTS ARE IN ACC. FREE AND FORGET ANY OTHER REGISTERS
!
 TYPE=TYPEP
 REGISTER(BREG)=0; GRUSE(BREG)=0
 GRUSE(ACCR)=0
 OPND1_PTYPE=+TYPE
 OPND1_XB=0; OPND1_D=ACCR
 ENTER LAB(PLABEL,B'11',LEVEL);! LABEL AT END OF EXP ROUTINE
 END 
ROUTINE REXP
!***********************************************************************
!* CALLS A PERM ROUTINE TO PERFORM REAL**REAL *
!***********************************************************************
 IF REGISTER(BREG)>0 THEN BOOT OUT(BREG)
 LOAD(OPND1,ACCR,2) UNLESS OPND1_FLAG=8
 LOAD(OPND2,ACCR,2)
 PPJ(0,14)
END 
END 
 ROUTINE REDUCE ENV(INTEGERNAME HEAD)
!***********************************************************************
!* HEAD HAS AN ENVIRONMENT - THIS ROUTINE REMOVES ANYTHING *
!* INCOMPATIBLE WITH THE CURRENT REGISTER STATE *
!***********************************************************************
INTEGER I,J,K,REG,USE
RECORDNAME LCELL(LISTF)
INTEGERNAME OHEAD
 OHEAD==HEAD
 WHILE OHEAD#0 CYCLE 
 LCELL==ASLIST(OHEAD)
 K=LCELL_S3
 REG=K>>8; USE=K&255
 UNLESS USE=GRUSE(REG) AND C 
 LCELL_S1=GRINF(REG) THEN C 
 POP(OHEAD,I,J,K) ELSE OHEAD==LCELL_LINK
 REPEAT 
END 
 INTEGERFN REVERSE(INTEGER MASK)
!***********************************************************************
!* REVERSE THE MASK FOR A JCC(MASK<=15),JAT(>15) OR JAF(>31 *
!***********************************************************************
 IF MASK>15 THEN MASK=MASK!!X'30' ELSE MASK=MASK!!15
 RESULT =MASK
END 
 ROUTINE ENTER LAB(INTEGER LAB,FLAGS,LEVL)
!***********************************************************************
!* ENTER A NEW LABEL ON THE LABEL LIST FOR THE CURRENT LEVEL *
!* 2**0 OF FLAGS = 1 CONDITIONAL ENTRY *
!* 2**1 OF FLAGS = 1 UPDATE ENVIRONMENT *
!* 2**2 OF FLAGS = 1 REPLACE ENV =0 MERGE ENV *
!* THE LABEL LIST *
!* S1 = LABEL NO *
!* S2 = ENVIRONMENT LIST << 16 ! UNFILLED JUMPS LIST *
!* S3 = LEVEL <<24 ! LABEL ADDR *
!***********************************************************************
INTEGER CELL,AT,ENVHEAD,JUMPHEAD,INSTRN,L,OLDCELL
RECORDNAME LCELL(LISTF)
!
! MAP CELL ONTO CORRECT LIST CELL =TAGSCELL FOR USER LABELS
!
 FLAGS=FLAGS&1 IF PARMOPT#0
 IF LAB<=NNAMES THEN CELL=TAGS(LAB) ELSE START 
 CELL=LABEL(LEVL); OLDCELL=0
 WHILE CELL>0 CYCLE 
 EXIT IF ASLIST(CELL)_S1=LAB
 OLDCELL=CELL
 CELL=ASLIST(CELL)_LINK
 REPEAT 
 FINISH 
 IF CELL<=0 THEN START ; ! LABEL NOT KNOWN
 IF FLAGS&1=0 THEN START ;! UNCONDITIONAL ENTRY
 PUSH(LABEL(LEVL),LAB,0,LEVEL<<24!CA)
 IF INCLUDE HANDCODE=NO THEN START 
 CYCLE L=0,1,7
 GRUSE(L)=0
 REPEAT 
 FINISH ELSE START 
 *LSQ_0
 *LCT_GRUSE+4
 *ST_(CTB +0)
 *ST_(CTB +4)
 FINISH 
 FINISH 
 RETURN 
 FINISH 
!
! LABEL HAS BEEN REFERENCED - FILL IN ITS ADDRESS
!
 LCELL==ASLIST(CELL)
 IF LCELL_S3&X'FFFFFF'# 0 THEN FAULT(2,LAB) AND RETURN 
 LCELL_S3=LEVEL<<24!CA
!
! SORT OUT ENVIRONMENTS - AS DIRECTED BY FLAGS
!
 JUMPHEAD=LCELL_S2
 ENVHEAD=JUMPHEAD>>16
 JUMPHEAD=JUMPHEAD&X'FFFF'
 IF FLAGS&2=0 THEN START 
 IF INCLUDE HANDCODE=NO THEN START 
 CYCLE L=0,1,7
 GRUSE(L)=0
 REPEAT 
 FINISH ELSE START 
 *LSQ_0
 *LCT_GRUSE+4
 *ST_(CTB +0)
 *ST_(CTB +4)
 FINISH 
 CLEAR LIST(ENVHEAD) IF ENVHEAD#0
 FINISH ELSE START 
 REMEMBER IF FLAGS&4=0
 RESTORE (ENVHEAD)
 ENVHEAD=0
 MERGE INFO IF FLAGS&4=0
 FINISH 
!
! NOW FILL JUMPS TO THIS LABEL - JUMP LIST FORMAT GIVEN IN 'ENTER JMP'
!
 WHILE JUMPHEAD#0 CYCLE 
 POP(JUMPHEAD,AT,INSTRN,L)
 FAULT(12,LAB) IF L<LEVEL
 PLUG(1,AT,INSTRN!(CA-AT)//2)
 REPEAT 
 LCELL_S2=0
 IF LAB> NNAMES THEN START 
 IF OLDCELL#0 THEN POP(ASLIST(OLDCELL)_LINK,AT,AT,AT) C 
 ELSE POP(LABEL(LEVL),AT,AT,AT)
 FINISH 
 END 
 ROUTINE ENTER JUMP(INTEGER MASK,LAB,FLAGS)
!***********************************************************************
!* IF LAB HAS BEEN ENCOUNTERED THEN PLANT A JCC OTHERWISE ENTER *
!* THE LABEL IN THE LABEL LIST AND ATTACH THE JUMP TO IT SO IT *
!* CAN BE PLANTED WHEN THE LABEL IS FOUND *
!* THE LABEL LIST IS DESCRIBED UNDER 'ENTER LAB' *
!* THE JUMP SUB-LIST HAS THE FORM *
!* S1= ADDR OF JUMP *
!* S2=INSTRN *
!* S3=LEVEL *
!* *
!* FLAGS BITS SIGNIFY AS FOLLOWS *
!* 2**0 =1 JUMP IS KNOWN TO BE SHORT *
!* 2**1 =1 ENVIRONMENT MERGEING REQUIRED *
!***********************************************************************
INTEGER AT,CELL,J,JJ,LABADDR,I,ENVHEAD,OLDENV,JCODE,LEVL
RECORDNAME LCELL(LISTF)
 FLAGS=FLAGS&1 IF PARMOPT#0
 ENVHEAD=0; AT=CA; LEVL=LEVEL
 IF LAB<21000 THEN FLAGS=FLAGS&X'FE'; ! SF OR USER LAB=LONG
 IF LAB<=NNAMES THEN START 
 CELL=TAGS(LAB)
 LEVL=ASLIST(CELL)_S1>>8&63; ! OLDI
 FLAGS=FLAGS&X'FD'; ! NO MERGE
 FINISH ELSE START 
 CELL=LABEL(LEVL)
 WHILE CELL#0 CYCLE 
 EXIT IF ASLIST(CELL)_S1=LAB
 CELL=ASLIST(CELL)_LINK
 REPEAT 
 FINISH 
 JCODE=OCODE(MASK)
 -> FIRSTREF IF CELL<=0
 LCELL==ASLIST(CELL)
 LABADDR=LCELL_S3&X'FFFFFF'
 -> NOT YET SET IF LABADDR=0
 I=(LABADDR-CA)//2
 FAULT(12,LAB) IF LCELL_S3>>24>LEVEL
 IF JCODE>6 THEN PSF1(JCODE,0,I) ELSE C 
 PF3(JCODE,MASK&15,0,I)
 RETURN 
FIRSTREF: ! FIRST REFERENCE TO A NEW LABEL
 IF LAB>NNAMES AND FLAGS&2#0 THEN GET ENV(ENV HEAD)
 PUSH(LABEL(LEVL),LAB,ENVHEAD<<16,0)
 CELL=LABEL(LEVL)
 LCELL==ASLIST(CELL)
 -> CODE
NOT YET SET: ! LABEL REFERENCED BEFORE
 IF LAB>NNAMES AND FLAGS&2#0 THEN START 
 I=LCELL_S2
 OLDENV=I>>16
 REDUCE ENV(OLD ENV)
 LCELL_S2=OLDENV<<16!I&X'FFFF'
 FINISH 
CODE: ! ACTUALLY PLANT THE JUMP
 IF JCODE>6 THEN I=JCODE<<24!3<<23 C 
 ELSE I=JCODE<<24!(MASK&15)<<21
 J=LCELL_S2
 JJ=J&X'FFFF'
 PUSH(JJ,CA,I,LEVEL)
 LCELL_S2=J&X'FFFF0000'!JJ
 PCONST(I)
 END 
 ROUTINE MERGE INFO
!***********************************************************************
!* MERGE THE CURRENT STATUS OF THE REGISTERS WITH THE VALUES *
!* AT THE START OF THE CONDITIONAL CLAUSE. THIS PERMITS THE *
!* THE COMPILER TO REMEMBER UNCHANGED REGISTERS BUT NOT THOSE *
!* WHICH DEPEND ON A PARTICULAR RUN TIME ROUTE BEING TAKEN *
!***********************************************************************
 INTEGER I,J
 CYCLE J=0,1,4; I=GRMAP(J)
 GRUSE(I)=0 UNLESS SGRUSE(I)=GRUSE(I) AND SGRINF(I)=GRINF(I)
 REPEAT 
 END 
 ROUTINE REMEMBER
INTEGER I,J
 CYCLE J=0,1,4; I=GRMAP(J)
 SGRUSE(I)=GRUSE(I)
 SGRINF(I)=GRINF(I)
 REPEAT 
END 
 ROUTINE CSNAME(INTEGER Z,REG)
!***********************************************************************
!* COMPILE A SPECIAL NAME - PTYPE=X'1006' (=%ROUTINE %LABEL) *
!* THEIR TRUE PTYPE IS IN GLOBAL ARRAY TSNAME. *
!* SNINFO HAS A FOUR BYTE RECORD FOR EACH NAME (%BI FLAG,PTR, *
!* %SI XTRA). THE TOP BITS OF FLAG CATEGORISE AS FOLLOWS:- *
!* 2**7 SET FOR IMPLICITLY SPECIFIED CONSTRUCT A %SPEC *
!* 2**6 SET FOR IOCP CALL *
!* 2**4 SET IF AD-HOC CODE PLANTED BY THIS ROUTINE *
!* 2**2-2**0 HOLD NUMBER OF PARAMS *
!* *
!* THE FULL SPECS ARE AS FOLLOWS:- *
!* 0=%REALFN ABS(%REAL VALUE) *
!* 1=%INTEGERFN IABS(%INTEGER VALUE) *
!* 2=%INTEGERFN SIGN(%REAL VALUE) *
!* 3=%INTEGERFN ENTIER(%REAL VALUE) *
!* 4=%ROUTINE CLOSESTREAM(%INTEGER STRM) *
!* 5=%LONGREALFN SQRT(%LONGREAL X) *
!* 6=%LONGREALFN SIN(%LONGREAL X) *
!* 7=%LONGREALFN COS(%LONGREAL X) *
!* 8=%LONGREALFN ARCTAN(%LONGREAL X) *
!* 9=%LONGREALFN LN(%LONGREAL X) *
!* 10=%LONGREALFN EXP(%LONGREAL X) *
!* 11=%REALFN MAXREAL *
!* 12=%REALFN MINREAL *
!* 13=%INTEGERFN MAXINT *
!* 14=%REALFN EPSILON *
!* 15=%ROUTINE FAULT(%STRINGNAME FNO,%REAL VALUE) *
!* 16=%ROUTINE STOP *
!* 17=%ROUTINE INSYMBOL(%INTEGER CH,%STRING STR,%INTEGERNAME SYM)*
!* 18=%ROUTINE OUTSYMBOL(%INTEGER CH,%STRING STR,%INTEGER SYM) *
!* 19=%ROUTINE INREAL(%INTEGER CH,%LONGREALNAME NUMBER) *
!* 20=%ROUTINE OUTREAL(%INTEGER CHANNEL,%LONGREAL NUMBER) *
!* 21=%ROUTINE ININTEGER(%INTEGER CH,%INTEGERNAME INT) *
!* 22=%ROUTINE OUTTERMINATOR(%INTEGER CHANNEL) *
!* 23=%ROUTINE OUTINTEGER(%INTEGER CHANNEL,VALUE) *
!* 24=%ROUTINE OUTSTRING(%INTEGER CHANNEL,%STRING STRING) *
!* 25=%INTEGERFN LENGTH(%STRING(255) S) *
!* 26=%REALFN CPUTIME *
!* AND 27-39 ARE THE IMP IO ROUTINES :- *
!* SELECTINPUT,SELECTPOUTPUT,NEWLINE,SPACE,NEWLINES,SPACES, *
!* NEXTSYMBOL PRINTSYMBOL,READSYMBOL,READ,NEWPAGE,PRINT, *
!* AND PRINTSTRING. READ IS A FUNCTION AS IS ALGOLS WONT *
!* 40=%INTEGERFN CODE(%STRING(1) CHAR) *
!* 41=%LONGREALFN READ1900 *
!* 42=%ROUTINE PRINT1900(%LONGREAL X,%INTEGERM,N) *
!* 43=%ROUTINE OUTPUT(%LONGREAL X) *
!* 44=%BOOLEANFN READ BOOLEAN *
!* 45=%ROUTINE WRITE BOOLEAN(%BOOLEAN BOOL) *
!* 46=%ROUTINE WRITE TEXT(%STRINGNAME TEXT) *
!* 47=%ROUTINE COPYTEXT(%STRINGNAME TEXT) *
!* 48=%INTEGERFN READCH *
!* 49=%INTEGERFN NEXTCH *
!* 50=%ROUTINE PRINTCH(%INTEGER CH) *
!* 51=%ROUTINE SKIPCH *
!* 52=%ROUTINE MONITOR *
!* 53=%ROUTINE OPENDA(%INTEGER CHANNEL) *
!* 54=%ROUTINE OPENSQ(%INTEGER CHANNEL) *
!* 55=%ROUTINE CLOSEDA(%INTEGER CHANNEL) *
!* 56=%ROUTINE CLOSESQ(%INTEGER CHANNEL) *
!* 57=%ROUTINE PUTDA(%INTEGER CH,%INTEGERNAME SECT,%GENERAL A) *
!* 58=%ROUTINE GETDA(%INTEGER CH,%INTEGERNAME SECT,%GENERAL A) *
!* 59=%ROUTINE PUTSQ(%INTEGER CH,%GENERALARRAY A) *
!* 60=%ROUTINE GETSQ(%INTEGER CH,%GENERALARRAY A) *
!* 61=%ROUTINE RWNDSQ(%INTEGER CHANNEL) *
!* 62=%ROUTINE INCHAR==INSYMBOL *
!* 63=%ROUTINE OUTCHAR==OUTSYMBOL *
!* 64=%ROUTINE PAPERTHROW==NEWPAGE *
!* 65=%ROUTINE PUTARRAY(%INTEGER CH,%INTEGERNAME S,%GENERAL A) *
!* 65=%ROUTINE GETARRAY(%INTEGER CH,%INTEGERNAME S,%GENERAL A) *
!***********************************************************************
 SWITCH ADHOC(1:7)
 CONSTINTEGERARRAY SNINFO(0:LAST SNAME)=C 
 X'11010024',X'11020024',X'11030024',X'11050024',
 X'80190000',X'80010000'(3),
 X'80010000'(3),X'80000000',
 X'80000000'(3),X'802D0000',
 X'10040001',X'80060000',X'800A0000',X'800E0000',
 X'80030000',X'801B0000',X'80110000',X'80130000',
 X'80160000',X'80110000',X'80000000',X'80190000',
 X'80190000',X'80000000'(2),X'80190000',
 X'80190000',X'80000000',X'80190000',X'801E0000',
 X'80000000'(2),X'80200000',X'80110000',X'11060024',
 X'80000000',X'80200000',X'80010000',X'80000000',
 X'80240000',X'80110000'(2),X'80000000',
 X'80000000',X'80190000',X'80000000',X'10070001',
 X'80190000'(4),
 X'80260000'(2),X'802A0000'(2),
 X'80190000',X'80060000',X'800A0000',X'80000000',
 X'80260000'(2);
!
! SNPARAMS HOLDS NUMBER AND PTYPE OF FORMAL PARAMETER FOR IMPLICITLY
! SPECIFIED EXTERNAL ROUTINES. A POINTER IN SNINFO MEANS THAT NO
! DUPLICATES NEED TO BE RECORDED.
! FIRST WORD OF GROUP HAS (THUNKS&PSIMPLE)<<8! NO OF PARAMS
! THE REMAINDER ARE THE TYPE OF EACH PARAM
!
 CONSTINTEGERARRAY SNPARAMS(0:47)=0,
 1,2, 2,1,2, X'13',1,5,X'101',
 X'13',1,5,1, X'12',1,X'102', X'11',5,
 X'12',1,1, X'12',1,5, X'11',1,
 X'12',1,X'101',X'11',X'101', 3,2,1,1,
 1,3, 3,1,X'101',X'110', 2,1,X'110',
 2,5,2;
! KEY TO PARAMETER TABLE
! 0 X0 == (NO PARAMS)
! 1 X1 == (%LONGREAL X)
! 3 X3 == (%INTEGER I,%LONGREAL X)
! 6 X6 == (%INTEGER I,%STRING S,%INTEGERNAME J)
! 10 XA == (%INTEGER I,%STRING S,%INTEGERNAME J)
! 14 XE == (%INTEGER I,%LONGREALNAME X)
! 17 X11 == (%STRING S)
! 19 X13 == (%INTEGER I,J)
! 22 X16 == (%INTEGER I,%STRING S)
! 25 X19 == (%INTEGER I)
! 27 X1B == (%INTEGER I,%INTEGERNAME J)
! 30 X1E == (%INTEGERNAME I)
! 32 X20 == (%LONGREAL X,%INTEGER I,J)
! 36 X24 == (%BOOLEAN B)
! 38 X26 == (%INTEGER I,%INTEGERNAME J,%GENERALARRAY A)
! 42 X2A == (%INTEGER I,%GENERALARRAY A)
! 43 X2D == %STRING S,%LONGREAL VALUE)
!
 CONSTSTRING (13)ARRAY SNXREFS(0:LAST SNAME)=C 
 "ABS","IABS","SIGN",
 "INTPT","CLOSESTREAM","ISQRT","ISIN",
 "ICOS","AARCTAN","ILOG","IEXP",
 "MAXREAL","MINREAL","MAXINT","EPSILON",
 "AFAULT","STOP","INSYMBOL","OUTSYMBOL",
 "INREAL","OUTREAL","ININTEGER",
 "OUTTERMINATOR",
 "OUTINTEGER","OUTSTRING","LENGTH","CPUTIME",
 "ASELIN","ASELOU","ALGNWL","ALGSPC",
 "ALGNLS","ALGSPS","ANXTSY","APRSYM",
 "ARDSYM","ALREAD","ALGPTH","PRINT",
 "PRSTNG","AICODE","READ1900","PRINT1900",
 "OUTPUT","READBOOLEAN","WRITEBOOLEAN",
 "WRITETEXT","COPYTEXT","ALRDCH","ALNXCH",
 "ALPRCH","ALSKCH","ALGMON","OPENDA",
 "OPENSQ","CLOSEDA","CLOSESQ","PUTDA",
 "GETDA", "PUTSQ", "GETSQ", "RWNDSQ",
 "INSYMBOL","OUTSYMBOL","ALGPTH","PUTARRAY",
 "GETARRAY";
CONSTLONGINTEGER ONE=1,CODED=X'C007C18E03068000';! BITMASK FOR CODE DEPENDENT
!
INTEGER ERRNO,FLAG,POINTER,OPHEAD,OPBOT,PIN,SNNO,SNNAME,NAPS, C 
 SNPTYPE,JJ,XTRA,B,D,SNINF,P0
STRING (16)REFNAME
!
 SNNAME=A(P)
 SNNO=K; ! INDEX INTO SNINFO
 IF EBCDIC=0 OR ONE<<SNNO&CODED=0 THEN C 
 REFNAME="S#" ELSE REFNAME="S#E"
 REFNAME=REFNAME.SNXREFS(SNNO)
 TESTAPP(NAPS); ! COUNT ACTUAL PARAMETERS
 PIN=P; P=P+1
 SNPTYPE=TSNAME(SNNO)
 SNINF=SNINFO(SNNO)
 XTRA=SNINF&X'FFFF'
 POINTER=(SNINF>>16)&255
 FLAG=SNINF>>24
!
! THE IMPLICITLY SPECIFIED ROUTINE ARE THE EASIEST OF ALL TO DEAL WITH.
! JUST SET UP THE EXTERNAL SPEC & PARAMETERS. THEN A RECURSIVE CALL
! OF CNAME THEN FINDS THE ROUTINE UNDER ITS TRUE COLOURS AND COMPILES
! THE CALL. ALL CALLS EXCEPT THE FIRST ARE DEALT WITH DIRECTLY BY CNAME.
! ALL NONTRIVIAL ROUTINES SHOULD BE DEALT WITH IN THIS MANNER
!
 IF Z=13 AND FLAG&X'80'=0 START ; ! RT PARAM
 FLAG=X'80'; ! GIVE FORMAL PROCEDURE
 IF SNNO=1 THEN POINTER=25 ELSE POINTER=1
 IF SNNO=16 OR SNNO=52 THEN POINTER=0
 IF SNNO=40 THEN POINTER=16
 FINISH 
!
 IF FLAG&X'80'#0 THEN START 
 CXREF(REFNAME,PARMDYNAMIC,2,JJ);! JJ SET WITH REF DISPLACEMENT
 IF SNNO=9 THEN LOGEPDISP=JJ
 IF SNNO=10 THEN EXPEPDISP=JJ
 OPHEAD=0; P0=SNPARAMS(POINTER)
 PUSH(OPHEAD,JJ,P0&15,P0>>4)
 OPBOT=OPHEAD
 K=OPHEAD; JJ=1; D=64
 P0=P0&15
 WHILE JJ<=P0 CYCLE 
 PTYPE=SNPARAMS(POINTER+JJ)
 IF PTYPE=2 THEN ACC=8 ELSE ACC=4
 D=(D&X'FFFF'+ACC-1)&(-ACC)
 IF PTYPE&X'F0'=0 THEN D=D!(PTYPE&X'F00')<<8
 BINSERT(OPHEAD,OPBOT,PTYPE,SNNAME,D)
 D=D+ACC
 JJ=JJ+1
 REPEAT 
 I=9; J=14; KFORM=0
 OLDI=0; PTYPE=SNPTYPE+4096
 USEBITS=3
 REPLACE TAG(SNNAME)
 P=PIN; CNAME(Z,REG); ! RECURSIVE CALL
 RETURN 
 FINISH 
!
! ALL ROUTINES EXCEPT THE IMPLICITS REQUIRE A CHECH THAT THE USE OF THE
! NAME IS LEGAL AND THAT THE CORRECT NO OF PARAMETERS(BOTTOM 2 BITS OF
! FLAG) HAS BEEN SUPPLIED. THE CHECK IS TRIVIAL - THE PROBLEM
! IS TO GET THE RIGHT ERROR NUMBER.
! XTRA HAS A BITMASK OF ALLOWED USES(IE ALLOWED Z VALUES)
!
 IF NAPS#FLAG&3 THEN ERRNO=19 AND ->ERREXIT
 JJ=1<<Z
 IF JJ&XTRA=0#Z THEN START ; ! ILLEGAL USE
 ERRNO=23
 ->ERR EXIT
 FINISH 
!
! A NUMBER OF INPUT-OUTPUT ROUTINES ARE MAPPED ONTO CALLS OF IOCP.
! THIS ARRANGEMENT HAS THE ADVANTAGE OF REQUIRING ONL 1 EXTERNAL REF
! IN THE GLA BUT HAS THE DISADVANTAGE THAT THE I-O ROUTINES CAN NOT
! BE PASSED AS RT-TYPE PARAMETERS AS WELL AS REQUIRING MESSY CODE
! HEREABOUTS. SNINF_PTR HOLD EITHER:-
! 1) THE IOCP ENTRY POINT NO
! OR 2) THE SYMBOL TO BE OUTPUT WITH 2**7 BIT SET
!
! THIS SECTION DEALS WITH SELECT INPUT,SELECT OUTPUT,NEWLINE,NEWPAGE
! SPACE,SKIP SYMBOL,PRINT SYMBOL,PRINT STRING
! AND PRINT CH
!
! %IF FLAG&X'40'#0 %THEN %START
! IOCPEP=POINTER
! %IF FLAG&3#0 %THEN %START; ! RT HAS PARAMS
! P=P+1
! %IF SNNO=37 %THEN CSTREXP(1,1) %ELSE CSEXP(1,1)
! %FINISH
! %IF IOCPEP>127 %THEN DUMP(X'41',1,IOCPEP&127,0,0) %AND IOCPEP=5
! CIOCP(IOCPEP); ! PLANT CALL OF IOCP
! ->OKEXIT
! %FINISH
!
! ADHOC CODING IS REQUIRED FOR THE REMAINING ROUTINES APART FROM
! A CHECK FOR NAMETYPE PARAMETERS. THE SWITCH NO IS KEPT IN POINTER
!
 ERRNO=22
 ->ADHOC(POINTER)
ADHOC(1): ! ABS
ADHOC(2): ! IABS
 B=3-POINTER; ! TYPE
 ->ERREXIT UNLESS A(P)=2
 D=A(P+2); P=P+3
 ->ERREXIT UNLESS 2<=D<=3
 CSEXP(ACCR,B,D)
 REG=NEST IF REG<0
 IF SNNO=1 THEN START 
 PF3(JAT,5,0,3)
 PSF1(IRSB,0,0)
 FINISH ELSE START 
 PF3(JAT,1,0,3)
 PSF1(RRSB,0,0)
 FINISH 
 GRUSE(ACCR)=0
 ->OKEXIT
ADHOC(3): ! SIGN
ADHOC(5): ! ENTIER
 ->ERREXIT UNLESS A(P)=2
 D=A(P+2); P=P+3
 ->ERREXIT UNLESS 2<=D<=3
 CSEXP(ACCR,2,D)
 REGISTER(ACCR)=1
 OPHEAD=RPPTR
 A(RPPTR)=2<<16!9
 A(RPPTR+1)=0
 A(RPPTR+3)=16-SNNO; ! 13 FOR ENTIER, 14 FOR SIGN
 A(RPPTR+4)=1
 A(RPPTR+6)=100
 RPPTR=RPPTR+9
 P0=P; EXPOP(OPHEAD,ACCR,1,1)
 P=P0; RPPTR=OPHEAD
 ->OKEXIT
ADHOC(4): ! STOP
 PPJ(15,16)
 ->OKEXIT
ADHOC(6): ! CODE
 ->ERREXIT UNLESS A(P)=2
 IF A(P+2)=2 THEN ->CONAM
 ->ERREXIT UNLESS A(P+2)=1
 B=A(P+5); D=B>>16&255; B=B>>24;! FIRST 2 CHARS
 IF A(P+4)=2 THEN START 
 IF B='E' AND D='L' THEN B=NL AND ->COD
 IF B='S'=D THEN B='%' AND ->COD
 FINISH 
 ->ERREXIT UNLESS A(P+4)=1
 IF B='_' THEN B=' '
 IF B='¬' THEN B=NL
 P=P-1
COD: IF EBCDIC#0 THEN B=ITOETAB(B)
 GET IN ACC(ACCR,1,0,0,B)
 GRUSE(ACCR)=5; GRINF(ACCR)=B
 P=P+6
 ->OKEXIT
CONAM: ! STRINGNAME PARAMETER
 P=P+3; SAVEIRS; CNAME(2,ACCR)
 ->ERREXIT UNLESS TYPE=5
 IF CODEPDISP=0 THEN CXREF(REFNAME,PARMDYNAMIC,2,CODEPDISP)
 PLANT(X'1804'); ! PRCL 4
 PLANT(X'4998'); ! ST TOS
 PSF1(LXN,1,16)
 PLANT(X'6C07'); ! RALN 7
 PF1(CALL,2,XNB,CODEPDISP)
 IF INCLUDE HANDCODE=NO THEN START 
 CYCLE JJ=0,1,7
 GRUSE(JJ)=0
 REPEAT 
 FINISH ELSE START 
 *LSQ_0
 *LCT_GRUSE+4
 *ST_(CTB +0)
 *ST_(CTB +4)
 FINISH 
 ->OKEXIT
ADHOC(7): ! MONITOR
 PLANT(X'6200'); ! LSS 0
 PLANT(X'4998'); ! ST TOS
 PPJ(0,2)
OKEXIT: ! NORMAL EXIT
 P=P+1
 PTYPE=SNPTYPE
 RETURN 
ERREXIT: ! ERROR EXIT
 FAULT(ERRNO,SNNAME)
 P=PIN+1; SKIP APP
 P=P-1; RETURN 
 END ; ! OF ROUTINE CSNAME
ROUTINE CALL THUNKS(INTEGER Z, REG, B, D)
!***********************************************************************
!* A THUNKS CONSISTS OF AN ESCAPE DESCRIPTOR AT D(B) WHICH POINTS*
!* TO STORED VALUES OF PC & LNB FOR THE THUNKS. THE BOUND FIELD *
!* IS SET TO NONZERO IF A STORE IS NOT ALLOWED *
!***********************************************************************
 BASE=B; AREA=-1
 GET IN ACC(DR,2,0,AREA CODE,D)
 IF Z=1 AND PARMARR#0 THEN PF3(JCC,14,0,4) AND PPJ(43,9)
 IF Z=0 THEN PSF1(MODD,0,0) AND RETURN 
 IF Z#1 THEN START 
 GET IN ACC(REG,BYTES(TYPE)>>2,2,7,0)
 FINISH 
END 
ROUTINE CANAME(INTEGER Z, BS, DP)
!***********************************************************************
!* BS & DP DEFINE THE POSITION OF THE ARRAY HEAD *
!* Z AS FOR CNAME. ON Z=1 (STORE INTO ARRAY) THE SUSBSCRIPTS *
!* ARE EVALUATED AND LEFT AS A RESULT DESCRIPTOR. THIS IS *
!* BECAUSE OF THE ALGOL DEFINITION OF LEFTPARTLIST *
!* IN-LINE CODE IS PLANTED EVEN IF PARM=NOARRAY IS REQUESTED *
!***********************************************************************
INTEGER HEAD1, HEAD2, HEAD3, NOPS, PTYPEP, KK, PP, C 
 JJ, TYPEP, ARRNAME, Q, ELSIZE, ARRP, PARAMS
 PP=P; TYPEP=TYPE; ARRP=PTYPE>>4&15
 JJ=J; PTYPEP=PTYPE
 ELSIZE=BYTES(TYPE)
 ARRNAME=A(P); ! NAME OF ENTITY
 PARAMS=A(P+1)
 TEST APP(Q); ! COUNT NO OF SUBSCRIPTS
!
! CHECK CORRECT NO OF SUBSCRIPTS PROVIDED. HOWEVER ENTITIES PASSED
! AS %<TYPE>ARRAYNAME HAVE NO DIMENSION . THIS SECTION SETS THE
! DIMENSION FROM THE FIRST USE OF THE NAME.
!
 IF JJ=0 THEN START ; ! 0 DIMENSIONS = NOT KNOWN
 ASLIST(TCELL)_S1=( ASLIST(TCELL)_S1!Q)
 ! DIMSN IS BOTTOM 4 BITS OF TAG
 JJ=Q
 KFORM=ASLIST(TCELL)_S3&X'FFFF'
 IF KFORM#0 THEN ASLIST(KFORM)_S2=(Q<<16!ASLIST(KFORM)_S2)
 FINISH 
 IF JJ=Q AND PARAMS=1 START ; ! CORRECT DIMENSIONALITY
!
! FOR IN-LINE CODE WE SET UP A CHAIN OF REVERSE POLISH OPERATIONS TO
! EVALUATE THE VARIOUS SUBSCRIPTS,MULTIPLY BY THE MULTIPLIERS AND
! ADD THEM TOGETHER.
!
 P=PP+3
 IF ARRP=2 AND JJ=1 THEN START 
 CSEXP(BREG,1,0); P=P+1
 FINISH ELSE START 
 HEAD3=0; NOPS=0
 HEAD1=RPPTR
!
! NOW PROCESS THE SUBSCRIPTS CALLINR ETORP TO CONVERT THE EXPRESSIONS
! TO REVERSE POLISH AND ADDING THE EXTRA OPERATIONS.
!
 CYCLE KK=1, 1, JJ; ! THROUGH THE SUBSCRIPTS
 ETORP(HEAD2,NOPS, 1);! SUBSCRIPT TO REVERSE POLISH
 RPPTR=RPPTR-3
 IF TYPE=2 THEN A(RPPTR)=13 AND A(RPPTR+1)=0 C 
 AND RPPTR=RPPTR+3
 P=P+2
 REPEAT 
 P=P-1
!
! N SUBSCRIPTS WILL REQUIRE (N-1) MULTIPLICATIONS AND ADDITIONS
!
 CYCLE KK=JJ,-1,1
 NOPS=(NOPS+1)!1<<24; ! TREAT DVM AS '*'
 A(RPPTR)=X'51'<<16
 A(RPPTR+1)=KK<<16!JJ
 A(RPPTR+2)=BS<<18!DP
 A(RPPTR+3)=28
 A(RPPTR+4)=ARRP
 RPPTR=RPPTR+6
 REPEAT 
!
! ADD OPERATORS TO THE BACK OF OPERANDS AND EVALUATE
!
 A(RPPTR)=100
 RPPTR=RPPTR+3
 PP=P
 EXPOP(HEAD1, BREG, NOPS, 5);! EVALUATE THE REVERSE POLISH LIST
 P=PP
 RPPTR=HEAD1
 FINISH 
 BASE=BS; DISP=DP
 ACCESS=3; AREA=-1;
 FINISH ELSE START 
 FAULT(18, ARRNAME)
 BASE=BS; DISP=DP
 ACCESS=3; AREA=-1;
 P=P+1; SKIP APP
 FINISH 
 ACC=ELSIZE
 PTYPE=PTYPEP; J=JJ
END ; ! OF ROUTINE CANAME
ROUTINE CNAME(INTEGER Z, REG)
!***********************************************************************
!* THIS IS THE MAIN ROUTINE FOR PROCESSING NAMES.CANAME,CSNAME *
!* AND CRNAME ARE ONLY CALLED FROM HERE,THE NAME (AND ANY PARAMS *
!* OR SUBNAMES) ARE INDEXED BY P WHICH IS ADVANCED. *
!* Z SPECIFIES ACTION AS FOLLOWS:- *
!* Z=0 COMPILE A ROUTINE CALL *
!* Z=1 SET BASE,INDEX AND DISP FOR A 'STORE' OPERATION *
!* Z=2 FETCH NAME TO 'REG' *
!* Z=3 SET ADDR(NAME) IN REG FOR PASSING BY NAME (TOP BYTE SET) *
!* Z=5 IF NAME IS IN A REGISTER THEN AS Z=2 ELSE SET BASE ETC *
!* Z=6->11 NOT NOW USED *
!* Z=12 SET BASE AND DISP TO POINT TO ARRAYHEAD *
!* Z=13 SET REG TO POINT TO 4 WORD ROUTINE DISCRIPTOR *
!* (INTERNAL ROUTINES FIRST CREATE THE DISCRIPTOR) *
!* *
!* REG (WHERE APPROPRIATE) IS SET AS FOLLOWS:- *
!* >=0 A REGISTER *
!* -1 MEANS CHOOSE ANY REGISTER *
!* IF A REGISTER IS CHOSEN THEN NEST IS SET WITH CHOICE *
!***********************************************************************
INTEGER JJ, KK, RR, LEVELP, DISPP, NAMEP, FNAME
SWITCH SW, MOD(0:7)
RECORDNAME LCELL(LISTF)
 FNAME=A(P); NAMEP=FNAME
 TCELL=TAGS(FNAME)
 IF TCELL<=0 THEN START 
 FAULT(16, FNAME)
 I=LEVEL; J=0; K=FNAME
 KFORM=0; SNDISP=0; ACC=4
 PTYPE=7; STORE TAG(K, N)
 N=N+4; COPY TAG(FNAME)
 LEVELP=I; DISPP=K
 FINISH ELSE START 
 LCELL==ASLIST(TCELL)
 KK=LCELL_S1; LCELL_S1=KK!X'8000'
 PTYPE=KK>>16; TYPE=PTYPE&7
 OLDI=KK>>8&15; I=KK>>4&15; LEVELP=I
 J=KK&15
 K=LCELL_S3>>16; DISPP=K
 FINISH 
 JJ=J; JJ=0 IF JJ=15
 ->NOT SET IF TYPE=7
 IF (Z=0 OR Z=13) AND PTYPE>>12=0 THEN FAULT(17,FNAME) C 
 AND ->NOT SET
 ->ARRHEAD IF Z=12
 ->RTNAME IF Z=13
 ->RTCALL IF PTYPE>>12#0
 ->SW(TYPE)
SW(6):
SW(0):
SW(4): !RECORD FORMAT NAME
ILLEGAL TYPE:
 FAULT(5, FNAME)
SW(7):
NOT SET: P=P+1; ! NAME NOT SET
 NEST=0; BASE=I; DISP=K; ACCESS=0
 PTYPE=1; TYPE=1
 SKIP APP; RETURN 
ARRHEAD: ! SET BASE & DISP FOR ARRAYHEAD
 BASE=I; ACCESS=0; DISP=K; AREA=-1
 NO APP; RETURN 
RTNAME: ! LOAD ADDR FOR RT-TYPE
 IF PTYPE=SNPT THEN CSNAME(Z, REG) AND P=P+1 AND RETURN 
 DISP=ASLIST(K)_S1; BASE=I
 IF PTYPE&X'100'#0 THEN START ;! TEST NAM BIT SET FORFORMAL PROCS
 AREA=-1
 GET IN ACC(REG,4,0,AREA CODE,DISP)
 FINISH ELSE START 
 IF J=14 THEN START ; ! EXTERNAL ROUTINE PASSED
 GET IN ACC(REG,2,0,0,0); ! ZERO ENVIRONMENT
 PF1(LUH,0,SET XORYNB(-1,-1),DISP)
 FINISH ELSE START 
 IF BASE=0 AND CPRMODE=2 START 
 PLANT(X'7883'); ! LD LNB+12 PLT DESRCPTR
 PSF1(INCA,0,DISP) UNLESS DISP=0
 GRUSE(DR)=0
 GET IN ACC(ACCR,2,0,0,0)
 FINISH ELSE START 
 PSF1(JLK,0,1); ! GET PC TO TOS
 RTJUMP(LDA,ASLIST(K)_S1); ! ADD N TO POINT @ ENTRY
 PLANT(X'1598'); ! INCA TOS - TO DR
 STORE CONST(JJ,4,X'E1000000',0)
 PF1(LDTB,0,PC,JJ)
 GRUSE(DR)=0
 GET IN ACC(ACCR,1,0,LNB,PTR OFFSET(BASE))
 PSF1(LUH,0,0); ! SPARE FIELD IN RT HDDR
 FINISH 
 PLANT(X'5998'); ! STD TOS DR TO STACKTOP
 PLANT(X'6B98'); ! LUH TOS DR TO TOP OF ACC
 FINISH 
 FINISH 
 NO APP; RETURN 
!
! SECTION TO DEAL WITH ALL NAMES INVOLVING ROUTINE CALL
!
RTCALL: ! FIRST CHECK
 IF TYPE=0 AND Z#0 THEN FAULT(23, FNAME) AND ->NOT SET
 ! RT NAME IN EXPRSN
 IF PTYPE=SNPT THEN CSNAME(Z,REG) AND RETURN 
 CRCALL(K); ! DEAL WITH PARAMS
 RETURN IF PTYPE=X'1000' OR PTYPE=X'1100'
 UNLESS Z=0 OR Z=2 OR Z=5 THEN START ; ! FUNCTIONS
 BASE=0; ACCESS=0; AREA=-1; DISP=0
 FINISH 
 IF REG=BREG THEN PLANT(X'499C');! ST BREG
 RETURN 
SW(5): ! TYPE=STRING
 ->ILLEGAL TYPE UNLESS Z=2; ! ONLY FETCH ALLOWED
 BASE=I; AREA=-1
 GET IN ACC(REG,2,0,AREA CODE,K)
 NO APP; RETURN 
SW(1): ! TYPE =INTEGER
SW(2): ! TYPE=REAL
SW(3): ! BOOLEAN
 IF PTYPE&X'F0'=0 THEN START 
 BASE=I; DISP=K
 ACCESS=0; AREA=-1
 IF A(P+1)=3 THEN P=P+1 ELSE NO APP
 FINISH ELSE START 
 CANAME(Z, I, K)
 PTYPE=PTYPE&X'F0FF'; ! NAM=0
 TYPE=PTYPE&7
 IF GRUSE(DR)=7 AND GRINF(DR)=NAMEP THEN AREA=7
 FINISH 
 KK=Z; KK=2 IF Z=5
 NAM=PTYPE>>8&15
 ->MOD(NAM<<2!KK&3)
MOD(1): ! SCALAR STORE
 IF PTYPE&X'F0'=0 THEN START 
 IF BASE=RLEVEL THEN AREA=LNB ELSE AREA=AREA CODE
 FINISH 
 RETURN 
MOD(6): ! SCALARNAME FETCH
 CALL THUNKS(2, REG, BASE, DISP)
 TEST ASS(REG) IF PARMCHK#0
 NEST=REG; RETURN 
MOD(2): ! SCALAR FETCH
 IF BASE=RLEVEL AND AREA<0 THEN AREA=LNB ELSE AREA=AREA CODE
 IF ACCESS=0 AND GRUSE(REG)=9 AND GRINF(REG)=NAMEP START 
 IF REGISTER(REG)=0 OR Z#5 START 
 IF REGISTER(REG)>0 THEN BOOT OUT(REG)
 NEST=REG; RETURN 
 FINISH 
 FINISH 
 IF PARMCHK=0 AND Z=5 THEN NEST=-1 AND RETURN 
 GET IN ACC(REG,BYTES(TYPE)>>2,ACCESS,AREA,DISP)
 IF ACCESS=3 THEN GRUSE(DR)=7 AND GRINF(DR)=NAMEP
 IF ACCESS=0 THEN GRUSE(REG)=9 AND GRINF(REG)=NAMEP
 IF PARMCHK=1 THEN START 
 IF REG=BREG THEN JJ=CPB ELSE JJ=UCP
 PF1(JJ,0,PC,PLABS(1))
 PCONST(JCC<<24!8<<21!((PLABS(5)-CA)//2)&X'3FFFF')
 FINISH 
 NEST=REG
 RETURN 
MOD(7): ! SCALAR NAME FETCH POINTER
 GET IN ACC(REG,2,0,AREA CODE,DISP)
 RETURN 
MOD(3): ! SCALAR FETCH ADDR
 IF ACCESS=3 THEN START 
 GET IN ACC(DR,2,0,AREA CODE,DISP) UNLESS AREA=7
 PLANT(X'179C'); ! MODD BREG
 GRUSE(DR)=0
 COPY DR IF REG#DR
 FINISH ELSE START 
 IF REG#DR THEN START 
 GET INACC(ACCR,1,0,LNB,PTR OFFSET(BASE))
 PSF1(IAD,0,DISP)
 PF1(LUH,0,PC,PARAM DES(TYPE))
 FINISH ELSE START 
 GET IN ACC(DR,2,0,PC,PARAM DES(TYPE))
 PSF1(LDA,1,PTR OFFSET(BASE))
 PSF1(INCA,0,DISP)
 FINISH 
 FINISH 
 NEST=REG
 RETURN 
MOD(5): ! SCALAR NAME STORE
 CALL THUNKS(1,-1,BASE,DISP)
 DISP=0; ACCESS=2; AREA=7
END 
ROUTINE NO APP
!***********************************************************************
!* CHECK FOR APP AND FAULT IF FOUND *
!***********************************************************************
 P=P+1
 IF A(P)=3 THEN P=P+1 ELSE START 
 FAULT(19,A(P-1))
 SKIP APP
 FINISH 
END 
ROUTINE GTHUNKS(INTEGER PTYPEP,PNAME)
!***********************************************************************
!* GENERATE A THUNKS FOR THE ACTUAL PARAMETER INDEXED BY P *
!* PTYPEP IF THE FORMAL PARAMETER TYPE. *
!***********************************************************************
INTEGER TYPEP, APALT, D, TOPREG, PL, NOSTORE, CTYPE, ICONST, AD, D1, D2
LONGREAL RCONST
SWITCH PARTYPE(0:7)
!
! FIRST CHECK FOR THUNKS PASSED ON AS THUNKS. IF FOUND THEN IT IS
! SUFFICIENT TO COPY THE THUNKS POINTER
!
 APALT=A(P); NOSTORE=0
 TYPEP=PTYPEP&7; TOPREG=15
 IF APALT=2 AND A(P+2)=3 START ; ! NAME,NO APP
 COPYTAG(A(P+1))
 IF ROUT=0 AND TYPE=TYPEP AND (ARR=0 OR TYPE=6) START 
 BASE=I; AREA=-1
 IF NAM=1 THEN GETINACC(ACCR,2,0,AREA CODE,K) ANDRETURN 
!
! A SIMPLE LOCAL NAME DOES NOT REQUIRE A PROPER THUNKS
! A NORMAL DESCRIPTOR IS MORE THAN ADEQUATE
!
 IF TYPEP<=3 THEN P=P+1 AND CNAME(3,ACCR) AND RETURN 
 FINISH 
 FINISH 
!
! CHECK FOR A SIMPLE CONSTANT BEING PASSED BY NAME. IF FOUND IT IS OK
! TO PASS A DESCRIPTOR TO THE CONSTANT AREA.
!
 IF APALT=3 AND A(P+1)=2 AND A(P+2+A(P+2))=2 AND C 
 A(P+4)=2 AND 1<=TYPEP<=2 AND PARMOPT=0 START 
 CTYPE=A(P+5)
 ICONST=0; RCONST=0
 IF CTYPE=1 THEN START 
 ICONST=A(P+6)
 RCONST=ICONST
 FINISH ELSE START 
 INTEGER(ADDR(RCONST))=A(P+6)
 INTEGER(ADDR(RCONST)+4)=A(P+7)
 ICONST=INT(RCONST) IF TYPEP=1
 FINISH 
!
 IF A(P+3)=2 THEN ICONST=-ICONST AND RCONST=-RCONST
 IF TYPEP=1 THEN AD=ADDR(ICONST) ELSE AD=ADDR(RCONST)
 STORE CONST(D2,BYTES(TYPEP),INTEGER(AD),INTEGER(AD+4))
 D2=D2&X'7FFFFFFF'; !N REMOVE CTABLE BIT
 D1=SIZE CODE(TYPEP)<<27+1
 PGLA(4,8,ADDR(D1))
 D=GLACA-8
 RELOCATE(D+4,D2,1)
 PUSH(GLARELOCS,D+4,D2,0); ! REMEMBER ADDR IN GLA FOR UPADTING
 AREA=-1; BASE=0
 GET IN ACC(ACCR,2,0,AREA CODE,D)
 RETURN 
 FINISH 
!
! A PROPER THUNKS IS NEEDED
!
 IF REGISTER(ACCR)#0 THEN BOOT OUT(ACCR)
 PLABEL=PLABEL-1; PL=PLABEL
 ENTER JUMP(0,PL,B'11')
! PF1(STLN,0,TOS,0)
! PF1(ST,0,TOS,0)
! PF1(STB,0,TOS,0)
! PF1(CPSR,0,BREG,0)
! PSF1(ADB,0,16)
! PF1(STB,0,TOS,0)
! PF1(STXN,0,TOS,0)
! PF1(STCT,0,TOS,0)
! PF1(LLN,1,0,4)
 PCLOD(118,122)
 IF INCLUDE HANDCODE=NO THEN START 
 CYCLE D=0,1,7
 GRUSE(D)=0
 REPEAT 
 FINISH ELSE START 
 *LSQ_0
 *LCT_GRUSE+4
 *ST_(CTB +0)
 *ST_(CTB +4)
 FINISH 
 ->PARTYPE(TYPEP)
PARTYPE(0):
PARTYPE(4):
PARTYPE(5):
PARTYPE(7):
ERROR:
 FAULT(22, PNAME)
 RETURN 
PARTYPE(3): ! BOOLEAN FORMAL
 ->ERROR UNLESS APALT=2 OR APALT=4
 ->COM
PARTYPE(1): ! INTEGER FORMAL
PARTYPE(2): ! REAL FORMAL
 ->ERROR UNLESS 2<=APALT<=3
COM:
 IF APALT=2 THEN START ; ! ACTUAL=<NAME><APP>
 COPYTAG(A(P+1))
 IF ROUT=0 AND TYPE=TYPEP START 
 P=P+1; CNAME(3, DR)
 ->THUNKSEND
 FINISH 
 FINISH 
 P=P+1
 CSEXP(ACCR, TYPEP, APALT)
 GET WSP(D, BYTES(TYPEP)>>2); ! 1 OR 2 WORDS
 PSF1(ST,1,D)
 PF1(LDTB,0,PC,PARAM DES(TYPEP))
 PSF1(LDA,1,PTR OFFSET(RLEVEL))
 PSF1(INCA,0,D)
 NOSTORE=4
THUNKSEND: ! EXIT SEQUENCE
! PF1(LCT,0,TOS,0)
! PF1(LXN,0,TOS,0)
! PF1(MPSR,0,TOS,0)
! PF1(LB,0,TOS,0)
! PF1(X'60',0,TOS,0); ! L =LOAD ACS
! PF1(LLN,0,TOS,0)
! PSF1(ESEX,0,0)
 PCLOD(124,127)
PASS DES:ENTER LAB(PL,B'111',LEVEL)
 GET WSP(D,2)
 PLANT(X'6398'); ! LSS TOS
 PSF1(ST,1,D)
 PSF1(STLN,1,D+4)
 PSF1(LSS,1,PTR OFFSET(RLEVEL))
 PSF1(IAD,0,D)
 PF1(LUH,0,PC,SPECIAL CONSTS(2)+NOSTORE)
 GRUSE(ACCR)=0
 RETURN 
PARTYPE(6): ! LABEL AND SWITCH
 IF PTYPEP&255>16 START 
 ->ERROR UNLESS APALT=2 AND A(P+2)=3
 P=P+1; GOTOLAB(3)
 ->PASS DES
 FINISH 
 IF APALT=3 OR APALT=5 THEN START 
 P=P+1; CDE(11-APALT<<1); ! MODE = 5 OR 3
 ->PASS DES
 FINISH 
 ->ERROR UNLESS APALT=2
 P=P+1; GOTOLAB(1)
 ->PASS DES
END 
ROUTINE FETCH STRING(INTEGER REG)
!***********************************************************************
!* FETCH A STRING POINTER FOR PASSING.P TO ALT OF ACTUAL PARAM *
!***********************************************************************
INTEGER I
 IF A(P)=1 THEN START 
 I=A(P+1)+EBCDIC
 PF1(LDRL,0,PC,STRLINK)
 PSF1(INCA,0,I) UNLESS I=0
 IF EBCDIC#0 THEN PSF1(LDB,0,A(P+2))
 IF REG#DR THEN COPY DR
 FINISH ELSE P=P+1 AND CNAME(2,REG)
 END 
INTEGERFN CHECK FPROCS(INTEGER ACTHEAD,FORMALHEAD)
!***********************************************************************
!* CHECK THAT THE PARAMETERLIST OF A ROUTINE BEING PASSED AS *
!* A PAREMETER IS THE SAME AS THAT GIVEN (VIA A COMMENT) FOR THE *
!* FORMAL PROCEDURE. REGRETABLY IF THE FORMAL IS OF A PROCEDURE *
!* WHICH IS ITSELF A FORMAL PROCEDURE THEN NO CHECK CAN BE MADE *
!* %IN MIXED LANGUAGE SITUATIONS NAM=1 (SUBSTITUTION),NAM=2 (REF) *
!* AND NAM=3 (FORTRAN RESULT) MUST BE TREATED AS EQUIVALENT *
!***********************************************************************
INTEGER NPS,FPTYPE,APTYPE
 NPS=ASLIST(FORMALHEAD)_S2
 RESULT =1 IF 0<=NPS#ASLIST(ACTHEAD)_S2
!
 WHILE NPS>0 CYCLE 
 MLINK(ACTHEAD)
 MLINK(FORMALHEAD)
 APTYPE=ASLIST(ACTHEAD)_S1
 FPTYPE=ASLIST(FORMALHEAD)_S1
 RESULT =1 UNLESS FPTYPE=APTYPE OR C 
 (APTYPE&X'F00'#0 AND FPTYPE&X'F00'#0 AND C 
 APTYPE&X'F0FF'=FPTYPE&X'F0FF')
 NPS=NPS-1
 REPEAT 
 RESULT =0; ! CORRESPONDENCE COMPLETE
END 
ROUTINE CRCALL(INTEGER CLINK)
!***********************************************************************
!* COMPILE A ROUTINE OR FN CALL *
!* THE PROCEDURE CONSIST OF THREE PARTS:- *
!* A) PLANT THE PARAMETER (IF ANY) *
!* B) ENTER THE ROUTINE OR FN *
!* C) FORGET ANY REGISTERS WHICH HOLD ENTITIES THAT CAN BE *
!* ALTERED BY THE CALLED PROCEDURE. *
!***********************************************************************
INTEGER II,PXTRA,DLINK,JJJ,NPARMS,PT,LP,PSIZE,III,RDISP, C 
 RTNAME,TL,MOVEPTR,PP,PNAM,NP,ALT,JJ
RECORDNAME LCELL(LISTF)
 JJJ=J; LP=I; DLINK=CLINK; TL=OLDI
 LCELL==ASLIST(CLINK)
 RTNAME=A(P);PT=PTYPE
!
! NOW CHECK THAT THE RIGHT NUMBER OF PARAMETERS HAVE BEEN PROVIDED
!
 TEST APP(NPARMS)
 P=P+1
 RDISP=LCELL_S1
 IF LCELL_S2#NPARMS THEN START 
 FAULT(19,RTNAME); ! WRONG NO OF PARAMETERS GIVEN
 SKIP APP
 RETURN 
 FINISH 
!
 SAVE IRS UNLESS REGISTER(ACCR)!REGISTER(BREG)=0
 PLANT(X'1804'); ! PRCL 4
 P=P+1
 MOVEPTR=5
 -> ENTRY SEQ IF NPARMS=0; ! NO PARAMETERS TO BE PLANTED
 NP=0; PP=P-2
!
NEXT PARM:CLINK=LCELL_LINK
 NP=NP+1
 P=PP+1
 ->ENTRY SEQ IF CLINK=0
 LCELL==ASLIST(CLINK)
 PSIZE=LCELL_S3>>16
 PNAM=LCELL_S2
 PXTRA=PNAM>>16
 PNAM=PNAM&X'FFF'
 PTYPE=LCELL_S1
 P=PP+2; PP=P+A(P)
 P=P+1
 ROUT=PTYPE>>12
 NAM=PTYPE>>8&15
 ARR=PTYPE>>4&15
 TYPE=PTYPE&15
 II=TYPE
 ALT=A(P); ! SYNTACTIC ALTERNATIVE OF APP
 IF PSIZE<=0 AND ((ROUT!ARR#0 AND ALT#2) OR C 
 (TYPE=5 AND ALT>2) OR (NAM=2 AND ALT#2) OR C 
 (PTYPE&X'F0F0'#0 AND TYPE<=2 AND (ALT=1 OR ALT>3))OR C 
 (PTYPE&X'F0FF'=3 AND ALT&1=1) C 
 OR (PTYPE&X'F0FF'<=2 AND (ALT=1 OR ALT>=4))) THEN C 
 FAULT(22,PNAM) AND ->NEXT PARM
!
! FOR RT TYPE PARAMS, PASS 1 WORD POINTING TO 4 WORDS SET
! UP AS CODE,GLA,EP ADDR & ENVIRONMENT
!
 IF ROUT=1 THEN START 
 II=PTYPE; P=P+1
 CNAME(13,ACCR); ! SET UP 4 WDS & SET PTR
 FAULT(21,PNAM) IF PTYPE>>12#0 AND C 
 (II&15#PTYPE&15 OR CHECK FPROCS(K,PXTRA)#0);! TYPE SIMILAR
 P=P+1
 MOVEPTR=MOVEPTR+4
STUFF: REGISTER(ACCR)=3
 ->NEXT PARM
 FINISH 
!
 IF ARR=0 AND (NAM=2 OR (NAM=3 AND ALT=2)) START 
 P=P+1; CNAME(3,ACCR)
 FAULT(22,PNAM) UNLESS II=PTYPE&7 AND PTYPE&X'F00'=0
 MOVEPTR=MOVEPTR+2
 ->STUFF
 FINISH 
!
 IF PSIZE>0 THEN START ; ! A THUNKS HAS BEEN SET
 GTHUNKS(PTYPE,PNAM)
 MOVEPTR=MOVEPTR+2
 ->STUFF
 FINISH 
!
! FOR ARRAYNAME PARAMETERS THE NO OF DIMENSIONS OF THE ARRAY IS
! DEDUCED FROM THE FIRST CALL AND STORED IN STREAM2 OF THE PARAMETER
! LIST. ON ANY SUBSEQUENT CALL ONLY ARRAYS OF THE SAME DIMENSION CAN
! BE PASSED
!
 IF ARR=1 THEN START 
 III=NAM; ! 0 FOR ARRAY BY VALUE
 IF A(P)=2 AND A(P+2)=3 THEN START 
 P=P+1; CNAME(12,ACCR); TYPE=PTYPE&7
 FAULT(22,PNAM) IF (PTYPE&X'F0') = 0; ! FAULT IF ACTUAL NOT ARRAY
 IF III=3 THEN JJ=2 ELSE JJ=4
 GET IN ACC(ACCR,JJ,0,AREA CODE,DISP)
 IF ARR#0 AND (II=0 OR II=TYPE OR C 
 (III=0 AND II#3#TYPE))START 
 IF II#0 THEN START ; ! NOT GENERAL ARRAY NAME
 IF PXTRA=0 THEN PXTRA=J AND C 
 LCELL_S2=PXTRA<<16!PNAM
 IF J=0 THEN START ;! ACTUAL DIMENSN UNKNOWN
 FNAME=A(P-2)
 J=PXTRA; II=TAGS(FNAME)
 ASLIST(II)_S1=(ASLIST(II)_S1!PXTRA)
 FINISH 
 FAULT(20,PNAM) IF 0#J#PXTRA AND III#3
 FINISH 
 MOVEPTR=MOVEPTR+JJ
 ->STUFF
 FINISH 
 FINISH 
 FAULT(22,PNAM)
 ->NEXT PARM
 FINISH 
!
 IF TYPE=5 THEN START ; ! STRINGS
 FETCH STRING(ACCR)
 FAULT(22,PNAM) UNLESS TYPE=5
 MOVEPTR=MOVEPTR+2
 ->STUFF
 FINISH 
!
! %IF TYPE=6 %THEN %START; ! LABEL BY VALUE
! %MONITOR
! %STOP
! %FINISH
 IF TYPE<=3 THEN START 
 P=P+1; III=NAM
 CSEXP(ACCR,TYPE,ALT)
 JJ=BYTES(II)>>2
 IF III=0 THEN MOVEPTR=MOVEPTR+JJ ELSE START 
 GET WSP(III,JJ)
 PSF1(ST,1,III)
 PSF1(LSS,0,III)
 PSF1(IAD,1,PTR OFFSET(RLEVEL))
 PF1(LUH,0,PC,PARAM DES(II))
 GRUSE(ACCR)=0
 MOVEPTR=MOVEPTR+2
 FINISH 
 ->STUFF
 FINISH 
 -> NEXT PARM
ENTRY SEQ: ! CODE FOR RT ENTRY
!
 IF REGISTER(ACCR)=3 THEN PLANT(X'4998') C 
 AND REGISTER(ACCR)=0; ! ST TOS
 PTYPE=PT; J=JJJ
!
! ORDINARY ROUTINES WILL AND RT PARAMS MAY REQUIRE AN EXTRA PARAMETER
! BEING LNB FOR THE LEVEL OF ROUTINE DECLARATION TO BE STACKED
!
 IF JJJ=14 THEN START ; ! EXTERNAL
 II=SET XORYNB(-1,-1); ! XNB TO PLT
 PSF1(RALN,0,MOVEPTR)
 PF1(CALL,2,II,RDISP)
 FINISH ELSE START 
 IF PTYPE&X'100'=0 THEN START ;! INTERNAL RT CALLS
 IF LP=0 THEN START 
 PLANT(X'7883'); ! LD LNB+12 PLT DESRCPTR
 PSF1(INCA,0,RDISP) UNLESS RDISP=0
 PSF1(RALN,0,MOVEPTR)
 PLANT(X'1FDC'); ! CALL (%DR)
 FINISH ELSE START 
 II=SET XORYNB(XNB,LP)
 PSF1(RALN,0,MOVEPTR)
 RT JUMP(CALL,ASLIST(DLINK)_S1)
 FINISH 
 FINISH ELSE START 
 AREA=-1; BASE=LP
 AREA=AREA CODE
 GET IN ACC(DR,2,0,AREA,RDISP)
 PSORLF1(LB,0,AREA,RDISP+12)
 PSORLF1(LSS,0,AREA,RDISP+8)
 PSF1(RALN,0,MOVEPTR); ! RAISE FOR NORMAL PARAMS
 PPJ(0,17); ! STACK EXTRA PARAM IF NEEDED
 PLANT(X'1FDC'); ! AND ENTER VIA DESCRPTR IN DR
 FINISH 
 FINISH 
 IF INCLUDE HANDCODE=NO THEN START 
 CYCLE II=0,1,7
 GRUSE(II)=0
 REPEAT 
 FINISH ELSE START 
 *LSQ_0
 *LCT_GRUSE+4
 *ST_(CTB +0)
 *ST_(CTB +4)
 FINISH 
 END 
ROUTINE SKIP EXP(INTEGER MODE)
!***********************************************************************
!* SKIP OVER AN EXPRESSION WHICH IS EITHER A CONDITIOAL EXPR *
!* OR A SIMPLE EXPRESSION. MODE AS FOR SKIP SEXP *
!* P<EXP>:='%IF'<BEXPR>'%THEN'<SIMPEXP>'%ELSE'<EXP>,<SIMPEXP> *
!* P<BEXP>:='%IF'<BEXPR>'%THEN'<SBEXPR>'%ESLE'<BEXPR> *
!***********************************************************************
INTEGER ALT, PIN
 PIN=P
 ALT=A(P); P=P+1; ! ALT OF EXPRESSION
 IF ALT=2 THEN SKIP SEXP(MODE) ELSE START 
 SKIP EXP(1)
 SKIP SEXP(MODE)
 SKIP EXP(MODE)
 FINISH 
END 
ROUTINE SKIP SEXP(INTEGER MODE)
!***********************************************************************
!* SKIPS OVER A BOOLEAN EXPRESSION *
!* MODE=0 FOR ARITHMETIC, =1 FOR BOOLEAN EXPRESSIO *
!* P TO HOLE IN <HOLE><+'><OPERAND><RESTOFEXRN> *
!* OR P TO <SBEXPR> WHERE :- *
!* P<SBEXPR>:=<BTERM><RESTOFSBEXPR> *
!***********************************************************************
INTEGER BOP, PIN, J
SWITCH ALT(1:8)
 PIN=P
 UNTIL BOP#1 CYCLE 
 BOP=A(P+2); P=P+3; ! BOP =ALT OF P<BOPERAND>
 ->ALT(BOP+MODE<<2)
ALT(1): ! <NAME> <APP>
ALT(6): ! <BOOLEAN NAME><APP>
 P=P+1; SKIP APP; ->END
ALT(2): ! <ARIRHMETIC CONSTANT>
 P=P+A(P)+1
 ->END
ALT(7): ! <BOOLEAN CONSTANT>
 P=P+1; ->END
ALT(3): ! '('<EXPRN>')'
ALT(8): ! '('<BEXPR>')'
 SKIP EXP(MODE); ->END
ALT(5): ! <EXPR><COMP><EXPR>
 SKIP EXP(0); P=P+1; SKIP EXP(0)
END: ! ANY MORE RESTOF BEXP?
 BOP=A(P)
 P=P+1 IF MODE#0
 REPEAT 
 P=P+1 IF MODE=0
END 
ROUTINE SKIP APP
!***********************************************************************
!* SKIP OVER ARRAY OR RT ACTUAL PARAMETER PART *
!* P POINTS TO THE ALT OF P<APP>. *
!***********************************************************************
INTEGER ALT, PIN
 PIN=P; ALT=A(P)
 IF ALT#3 THEN START 
 IF ALT=2 THEN START 
 P=P+1+A(P+1)
 WHILE A(P)=1 THEN P=A(P+2)+P+2
 FINISH ELSE START 
 WHILE A(P)=1 THEN P=P+1 AND P=P+A(P)
 FINISH 
 FINISH 
 P=P+1
END 
ROUTINE TEST APP(INTEGERNAME NUM)
!***********************************************************************
!* THIS ROUTINE COUNTS THE NUMBER OF ACTUAL PARAMETERS *
!* WHICH IT RETURNS IN NUM. *
!***********************************************************************
INTEGER PP, Q
 Q=0; PP=P; P=P+1; ! P ON NAME AT ENTRY
 IF A(P)=2 THEN START 
 Q=1; P=P+1+A(P+1)
 WHILE A(P)=1 THEN Q=Q+1 AND P=P+2+A(P+2)
 FINISH ELSE START 
 WHILE A(P)=1 CYCLE ; ! NO (MORE) PARAMETERS
 P=P+1; Q=Q+1
 P=P+A(P)
 REPEAT 
 FINISH 
 P=PP; NUM=Q
END 
ROUTINE TEST ASS(INTEGER REG)
!***********************************************************************
!* TEST ACC OR B FOR THE UNASSIGNED PATTERN *
!***********************************************************************
INTEGER OPCODE
 IF REG=BREG THEN OPCODE=CPB ELSE OPCODE=UCP
 PF1(OPCODE,0,PC,PLABS(1))
 PCONST(JCC<<24!8<<21!((PLABS(5)-CA)//2)&X'3FFFF')
END 
 ROUTINE CBPAIR(INTEGERNAME LB,UB)
!***********************************************************************
!* EXTRACT UPPER AND LOWER BOUNDS FROM A CONSTANT BOUND PAIR *
!***********************************************************************
 INTEGER KK,KKK,JJ,BP
 P=P+1; KK=0
 CYCLE JJ=1,1,2
 KKK=KK
 IF A(P)=2 THEN KK=-1 ELSE KK=1; ! EXTRACT SIGN
 BP=A(P+2)
 KK=KK*BP
 P=P+3
 REPEAT 
 IF KKK>KK THEN FAULT(43,0) AND KK=KKK
 LB=KKK; UB=KK
 END 
 ROUTINE GET WSP(INTEGERNAME PLACE,INTEGER SIZE)
!***********************************************************************
!* FIND OR CREATE A TEMPORARY VARIABLE OF 'SIZE' WORDS *
!***********************************************************************
 INTEGER J,K,L
 IF SIZE>4 THEN SIZE=0
 POP(AVL WSP(SIZE,LEVEL),J,K,L)
 IF K<=0 THEN START ; ! MUST CREATE TEMPORARY
 IF SIZE>1 AND N&7=0 THEN ODD ALIGN
 K=N
 IF SIZE=0 THEN N=N+268 ELSE N=N+SIZE<<2
 FINISH 
 PLACE=K
 PUSH(TWSPHEAD,K,SIZE,0) UNLESS SIZE=0
 END 
 ROUTINE RETURN WSP(INTEGER PLACE,SIZE)
 IF SIZE>4 THEN SIZE=0
 PUSH(AVL WSP(SIZE,LEVEL),0,PLACE,0)
 END 
 ROUTINE SET LINE
!***********************************************************************
!* UPDATE THE STATEMENT NO *
!***********************************************************************
 PCONST(X'63800000'!LINE)
 PSF1(ST, 1, DIAGINF(LEVEL)+4)
 GRUSE(ACCR)=5; GRINF(ACCR)=LINE
 END 
 ROUTINE SET USE(INTEGER R,U,I)
!***********************************************************************
!* NOTE THAT THE USE OF REGISTER 'R' IS NOW 'U' & 'I' *
!***********************************************************************
 GRUSE(R)=U ; GRINF(R)=I
 GRAT(R)=CA
 END 
ROUTINE SAVE IRS
!***********************************************************************
!* DUMP ACC AND-OR B ONTO THE STACK. USED BEFORE CALLING FNS *
!* IN EXPRESSIONS. *
!***********************************************************************
 IF REGISTER(BREG)>=1 THEN BOOT OUT(BREG)
 IF REGISTER(ACCR)>=1 THEN BOOT OUT(ACCR)
 IF REGISTER(DR)>=1 THEN BOOT OUT(DR)
END 
ROUTINE BOOT OUT(INTEGER REG)
!***********************************************************************
!* REMOVE TEMPORARIES FROM REG INTO LOCAL OR ONTO STACK *
!* IT IS VITAL THAT ACC IS STACKED FIRST BEFORE B OR DR *
!* OTHERWISE MIXUPS OCCUR WHEN PASSING MULTI-DIMENSION ARRAY *
!* ELEMENTS WITH FNS AS SUBSCRIPTS AS VALUE SCALARS *
!***********************************************************************
CONSTBYTEINTEGERARRAY BOOTCODE(0:7)=X'48',X'58',X'5C',0(4),X'5A';
INTEGER CODE,RR
RECORDNAME R(RD)
 CODE=BOOTCODE(REG)
 RR=REGISTER(REG)
! ABORT %UNLESS 1<=RR<=3 %AND CODE#0
 R==RECORD(OLINK(REG))
 IF RR=2 THEN START 
 IF R_D=0 THEN GET WSP(R_D,BYTES(R_PTYPE&7)>>2)
 PSF1(CODE,1,R_D)
 R_FLAG=7; R_XB=LNB<<4
 FINISH ELSE START 
 IF REG#ACCR AND (REGISTER(ACCR)=1 OR REGISTER(ACCR)=3)C 
 THEN BOOT OUT(ACCR)
 PLANT(CODE<<8!X'198'); ! "CODE" TOS
 IF RR=1 THEN R_FLAG=8 AND R_XB=TOS<<4
 FINISH 
 REGISTER(REG)=0
END 
ROUTINE COPY DR
!***********************************************************************
!* COPY THE DR TO ACC SAVING ANYTHING IN ACC *
!***********************************************************************
 IF REGISTER (ACCR)#0 THEN BOOT OUT(ACCR)
 PSF1(CYD,0,0)
 GRUSE(ACCR)=0
END 
ROUTINE CHANGE RD(INTEGER REG)
!***********************************************************************
!* CHANGE A RESULT DESCRIPTOR WHEN OPERAND IS STACKED *
!***********************************************************************
INTEGER I,RR
RECORDNAME OPND(RD)
 RR=REGISTER(REG)
! ABORT %UNLESS 1<=RR<=3
 OPND==RECORD(OLINK(REG))
 IF RR=1 THEN START ; ! CHANGE RESULT DESCRIPTOR
! ABORT %UNLESS OPND_FLAG=9 %AND OPND_XB>>4=REG
 OPND_FLAG=8; ! CHANGE TO 'STACKED'
 OPND_XB=TOS<<4
 FINISH 
 IF RR=2 START 
 OPND_FLAG=7; OPND_XB=LNB<<4
 FINISH 
END 
ROUTINE STORE TAG(INTEGER KK, SLINK)
INTEGER Q, QQ, QQQ, I
RECORDNAME LCELL(LISTF)
 Q=TAGS(KK)
 IF ASLIST(Q)_S1>>8&63=LEVEL THEN FAULT(7,KK) ELSE START 
 Q=PTYPE<<16!LEVEL<<8!RLEVEL<<4!J
! ABORT %UNLESS (KFORM!ACC)>>16=0
 QQQ=SLINK<<16!KFORM
 QQ=SNDISP<<16!ACC
 I=ASL
 IF I=0 THEN I=MORE SPACE
 LCELL==ASLIST(I)
 ASL=LCELL_LINK
 LCELL_LINK=TAGS(KK)!NAMES(LEVEL)<<18
 LCELL_S1=Q; LCELL_S2=QQ; LCELL_S3=QQQ
 TAGS(KK)=I
 NAMES(LEVEL)=KK
 FINISH 
END 
ROUTINE COPY TAG(INTEGER KK)
INTEGER QQ,QQQ
RECORDNAME LCELL(LISTF)
 TCELL=TAGS(KK)
 IF TCELL=0 THEN START ; ! NAME NOT SET
 TYPE=7; PTYPE=7
 ROUT=0; NAM=0; ARR=0; ACC=4
 I=-1; J=-1; K=-1; OLDI=-1
 KFORM=0; SNDISP=0
 FINISH ELSE START 
 LCELL==ASLIST(TCELL)
 KK=LCELL_S1
 LCELL_S1=KK!X'8000'; ! SET 'NAME USED' BIT
 QQ=LCELL_S2
 QQQ=LCELL_S3
 PTYPE=KK>>16; USEBITS=KK>>14&3
 OLDI=KK>>8&63; I=KK>>4&15; J=KK&15
 SNDISP=QQ//X'10000'
 ACC=QQ&X'FFFF'
 K=QQQ//X'10000'
 KFORM=QQQ&X'FFFF'
 TYPE=PTYPE&15
 ARR=PTYPE>>4&15
 NAM=PTYPE>>8&15
 ROUT=PTYPE>>12
 FINISH 
END 
ROUTINE REDUCE TAG
!***********************************************************************
!* AS COPY TAG FOR NAME AT A(P) EXCEPT:- *
!* 1) SPECIAL NAMES HAVE THEIR CORRECT PREC & TYPE SUBSTITUTED *
!***********************************************************************
 COPY TAG(A(P))
 IF PTYPE=SNPT THEN START 
 PTYPE=TSNAME(K); UNPACK
 ROUT=1
 FINISH ; ! TO AVOID CHECKING PARAMS
 END 
ROUTINE REPLACE TAG(INTEGER KK)
INTEGER P, Q
 P=TAGS(KK)
 Q=PTYPE<<16!USEBITS<<14!OLDI<<8!I<<4!J
 ASLIST(P)_S1=( Q)
 ASLIST(P)_S3=( K<<16!KFORM)
END 
ROUTINE UNPACK
 TYPE=PTYPE&15
 ARR=PTYPE>>4&15
 NAM=PTYPE>>8&15
 ROUT=PTYPE>>12
END 
ROUTINE PACK(INTEGERNAME PTYPE)
 PTYPE=ROUT<<12!NAM<<8!ARR<<4!TYPE
END 
ROUTINE PPJ(INTEGER MASK,N)
!***********************************************************************
!* PLANT A 'JCC MASK,PERMENTRY(N)' *
!* IF MASK=0 THEN PLANT A JLK *
!* IF MASK=-1 THEN PLANT A CALL TO PERM *
!***********************************************************************
INTEGER VAL, INSTRN, CODE
 CODE=OCODE(MASK)
 INSTRN=CODE<<24
 VAL=PLABS(N)
 IF CODE>6 THEN INSTRN=INSTRN!3<<23 ELSE C 
 INSTRN=INSTRN!(MASK&15)<<21
 IF VAL>0 THEN INSTRN=INSTRN!((VAL-CA)//2)&X'3FFFF' ELSE C 
 PUSH(PLINK(N),CA,INSTRN,0)
 PCONST(INSTRN)
 IF CODE>6 START 
 IF INCLUDE HANDCODE=NO THEN START 
 CYCLE VAL=0,1,7
 GRUSE(VAL)=0
 REPEAT 
 FINISH ELSE START 
 *LSQ_0
 *LCT_GRUSE+4
 *ST_(CTB +0)
 *ST_(CTB +4)
 FINISH 
 FINISH 
END 
INTEGERFN XORYNB(INTEGER USE,INF)
!***********************************************************************
!* CHECKS IF XNB OR YNB SET UP. IF NOT DECIDES WHICH TO OVERWRITE *
!***********************************************************************
 IF GRUSE(XNB)=USE AND GRINF(XNB)=INF THEN GRAT(XNB)=CA C 
 AND RESULT =XNB
 IF GRUSE(CTB)=USE AND GRINF(CTB)=INF THEN GRAT(CTB)=CA C 
 AND RESULT =CTB
 IF GRUSE(XNB)!GRUSE(CTB)=0 THEN START ;! BOTH REGS ARE FREE
 IF USE=3 THEN RESULT =CTB
 RESULT =XNB
 FINISH 
!
! IF ONLY ONE FREE THEN NO PROBLEM
 IF GRUSE(XNB)=0 THEN RESULT =XNB
 IF GRUSE(CTB)=0 THEN RESULT =CTB
!
! BOTH ARE IN USE. THIS IS WORTH CAREFUL CONSIDERATION AND EXPERIMENT
! A VALUE TABLE MAY BE USE AS MAY LOOK AHEAD. CURRENTLY TRY LRU
!
 IF GRAT(XNB)<GRAT(CTB) THEN RESULT =XNB
 RESULT =CTB
END 
INTEGERFN SET XORYNB(INTEGER WHICH,RLEV)
!***********************************************************************
!* SET EXTRA NAME BASE TO ADDRESS ROUTINE LEVEL 'RLEV' *
!* RLEV=0 FOR OWNS, =-1 FOR THE PLT THESE ARE THE SAME! BUT CODED*
!* SEPARATELY SO THAT THEY CAN BE SEPARATED IF NECESSARY *
!***********************************************************************
INTEGER USE,INF,OFFSET
 ABORT UNLESS -1<=RLEV<=RLEVEL
 IF RLEV<=0 THEN USE=3 AND INF=0 ELSE USE=4 AND INF=RLEV
 IF WHICH<=0 THEN WHICH=XORYNB(USE,INF)
 IF GRUSE(WHICH)=USE AND GRINF(WHICH)=INF THEN C 
 GRAT(WHICH)=CA AND RESULT =WHICH
 OFFSET=PTR OFFSET(RLEV)
 PSF1(LDCODE(WHICH),1,OFFSET)
 GRUSE(WHICH)=USE; GRINF(WHICH)=INF; GRAT(WHICH)=CA
 RESULT =WHICH
END 
ROUTINE ODDALIGN
!***********************************************************************
!* SETS N TO ODD WORD BOUNDARY. SINCE PRECALL ALSO SETS SF TO ODD *
!* WORD BOUNDARY THIS MEANS 64 BIT QUANTITIES ARE 64 BIT ALIGNED *
!* AND CAN BE REFERNCED IN A SINGL CORE CYCLE *
!***********************************************************************
 IF N&7=0 THEN RETURN WSP(N,1) AND N=N+4
END 
INTEGERFN PTROFFSET(INTEGER RLEV)
!***********************************************************************
!* RETURNS OFFSET FROM LNB OF RELEVANT ITEM IN THE CURRENT DISPLAY *
!* WHICH ENABLES TEXTTUAL LEVEL 'RLEV' TO BE ADDRESSED *
!* A FUNCTION IS USED TO ALLOW CHANGES IN THE DISPLAY FORMAT *
!***********************************************************************
 IF RLEV<=0 THEN RESULT =16
 RESULT =DISPLAY(RLEVEL)+(RLEV-1)<<2
END 
INTEGERFN AREA CODE
!***********************************************************************
!* RETURNS THE AREA CODE FOR ROUTINE LEVEL 'BASE' LOADING *
!* XNB WHERE THIS IS NEEDED *
!***********************************************************************
 IF AREA<0 THEN START 
 IF BASE=RLEVEL THEN AREA=LNB AND RESULT =LNB;! LOCAL LEVEL
 AREA=SET XORYNB(-1,BASE)
 FINISH 
 RESULT =AREA
END 
ROUTINE NOTE ASSMENT(INTEGER REG,VAR)
!***********************************************************************
!* NOTES THE ASSIGNMENT TO SCALAR VARIABLE 'VAR'. REMOVES ALL *
!* OLD COPIES FROM THE REGISTERS. IF VAR IS A SUBSTITUION *
!* PARAMETER ALL VARIABLES ARE REMOVED BECAUSE OF POSSIBLE SIDE *
!* EFFECTS. *
!***********************************************************************
INTEGER I,NAM
 I=TAGS(VAR)
 NAM=ASLIST(I)_S1>>24&15
 CYCLE I=0,7,7; ! ONLY ACC &BREG RELEVANT
 IF GRUSE(I)=9 AND (GRINF(I)=VAR OR NAM#0) THEN C 
 GRUSE(I)=0
 REPEAT 
 IF NAM=0 AND GRUSE(REG)<=3 THEN C 
 GRUSE(REG)=9 AND GRINF(REG)=VAR
END 
ROUTINE GET IN ACC(INTEGER REG,SIZE,ACCESS,AREA,DISP)
!***********************************************************************
!* LOADS THE REGISTER SPECIFIED ARRANGING FOR AUTOMATIC *
!* STACKING WHEN THIS IS NEEDED *
!* IT IS VITAL THAT ACC IS STACKED FIRST BEFORE B OR DR *
!* OTHERWISE MIXUPS OCCUR WHEN PASSING MULTI-DIMENSION ARRAY *
!* ELEMENTS WITH FNS AS SUBSCRIPTS AS VALUE SCALARS *
!***********************************************************************
INTEGER OPCODE
CONSTINTEGERARRAY GETCODE(0:7)=X'62',X'76',0(5),X'7A';
 OPCODE=GETCODE(REG)+SIZE&6
!
 IF REGISTER(REG)>0 THEN START 
 IF REGISTER(REG)=2 THEN BOOT OUT(REG) ELSE START 
 IF REG#ACCR AND (REGISTER(ACCR)=1 OR REGISTER(ACCR)=3)C 
 THEN BOOT OUT(ACCR)
 CHANGE RD(REG)
 REGISTER(REG)=0
 IF REG=ACCR THEN OPCODE=OPCODE-32 ELSE OPCODE=OPCODE-40
 FINISH 
 FINISH 
 PSORLF1(OPCODE,ACCESS,AREA,DISP)
 IF ACCESS>=2 THEN GRUSE(DR)=0
 GRUSE(REG)=0
END 
END 
IF ALLOW CODELIST=YES THEN START 
ROUTINE PRINT USE
CONSTSTRING (3)ARRAY REGS(0:7)='ACC',' DR','LNB','XNB',
 ' PC','LTB','TOS',' B';
CONSTSTRING (15)ARRAY USES(0:15) =' NOT KNOWN ',' I-RESULT ',
 ' TEMPORARY ',' PLTBASE ',
 ' NAMEBASE ',' LIT CONST ',
 ' TAB CONST ',' DESC FOR ',
 ' RECD BASE ',' LOCAL VAR ',
 ' FN RESULT ',
 ' ??? '(3),' SST BASE ',
 ' RT PARAM ';
CONSTSTRING (11)ARRAY STATE(-1:3)=C 
 ' LOCKED ',' FREE ',
 ' I-RESULT ',' TEMPORARY ',
 ' RT-PARAM ';
INTEGER I
 CYCLE I=0,1,7
 IF REGISTER(I)!GRUSE(I)#0 START 
 PRINTSTRING(REGS(I).STATE(REGISTER(I)). C 
 ' USE = '.USES(GRUSE(I)))
 IF 7<=GRUSE(I)<=10 THEN PRINTNAME(GRINF(I)) ELSE C 
 WRITE(GRINF(I),1)
 NEWLINE
 FINISH 
 REPEAT 
END 
FINISH 
END ; ! OF BLOCK CONTAINING PASS3
 ROUTINE MESSAGE(INTEGER N)
!***********************************************************************
!* OUTPUTS AN ERROR MESSAGE STORED IN A COMPRESSED FORMAT *
!* 2 (LABEL INVALID OR SET TWICE) *
!* 4 (SWITCH NAME NOT SET) *
!* 5 (LABEL NAME IN EXPRSSN) *
!* 7 (NAME SET TWICE) *
!* 8 (INVALID NAME IN VALUE LIST) *
!* 9 (INVALID PARAMETER SPECIFICATION) *
!* 10 (PARAMETER INCORRECTLY SPECIFIED) *
!* 11 (LABEL NOT SET) *
!* 12 (LABEL NOT ACCESSIBLE) *
!* 14 (TOO MANY ENDS) *
!* 15 (MISSING ENDS) *
!* 16 (NAME NOT SET) *
!* 17 (NOT PROCEDURE NAME) *
!* 18 (WRONG NO OF SUBSCRIPTS) *
!* 19 (WRONG NO OF PARAMETERS) *
!* 20 (PARAMETRIC ARRAY WRONG DIMENSION) *
!* 21 (PARAMETRIC PROCEDURE NOT VALID) *
!* 22 (ACTUAL PARAMETER NOT PERMITTED) *
!* 23 (PROCEDURE NAME IN EXPRSSN) *
!* 24 (VARIABLE IN BOOLEAN EXPRSSN) *
!* 25 (FOR VARIABLE INCORRECT) *
!* 26 (DIV OPERANDS NOT INTEGER) *
!* 27 (LOCAL IN ARRAY BOUND) *
!* 29 (INVALID NAME IN LEFTPART LIST) *
!* 34 (TOO MANY LEVELS) *
!* 35 (TOO MANY PROCEDURE LEVELS) *
!* 37 (ARRAY TOO MANY DIMENSIONS) *
!* 40 (DECLN MISPLACED) *
!* 42 (BOOLEAN VARIABLE IN EXPRSSN) *
!* 43 (ARRAY INSIDE OUT) *
!* 47 (ILLEGAL ELSE) *
!* 48 (SUB CHAR IN STMNT) *
!* 57 (BEGIN MISSING) *
!* 71 (UNACCEPTABLE SYMBOL) *
!* 72 (NAME NOT IN DICTIONARY) *
!* 73 (SUBSCRIPT UNACCEPTABLE) *
!* 74 (NAME ALREADY IN DICTIONARY) *
!* 75 (SPURIOUS DECIMAL POINT) *
!* 76 (UNACCEPTABLE EXPONENT) *
!* 77 (INTEGER CONSTANT TOO LARGE) *
!* 78 (REAL CONSTANT TOO LARGE) *
!* 79 (DECLN MISPLACED) *
!* 80 (TYPE MISMATCH) *
!* 98 (ADDRESSABILITY) *
!* 99 (ADDRESSABILITY) *
!* 102 (WORKFILE TOO SMALL) *
!* 103 (NAMES TOO LONG) *
!* 104 (TOO MANY NAMES) *
!* 105 (PROGRAM WITH EXTERNAL PROCEDURE) *
!* 106 (STRING CONST TOO LONG) *
!* 107 (ASL EMPTY) *
!* 108 (TOO MANY LEVELS) *
!* 127 (SEE ALGOL MANUAL) *
!***********************************************************************
 CONSTBYTEINTEGERARRAY WORD(0: 265)=0,C 
 2, 1, 2, 4, 5, 4, 6, 7,
 8, 4, 5, 1, 7, 9, 10, 7,
 7, 4, 5, 0, 8, 12, 7, 9,
 14, 9, 12, 16, 18, 0, 10, 16,
 21, 23, 0, 11, 1, 8, 4, 0,
 12, 1, 8, 25, 0, 14, 27, 28,
 29, 0, 15, 30, 29, 0, 0, 16,
 7, 8, 4, 0, 17, 8, 32, 7,
 0, 18, 34, 35, 36, 37, 19, 34,
 35, 36, 39, 20, 41, 43, 34, 44,
 21, 41, 32, 8, 46, 22, 47, 16,
 8, 48, 23, 32, 7, 9, 10, 24,
 50, 9, 52, 10, 25, 54, 50, 55,
 0, 26, 57, 58, 8, 60, 27, 62,
 9, 43, 63, 29, 12, 7, 9, 64,
 34, 27, 28, 67, 0, 35, 27, 28,
 32, 67, 37, 43, 27, 28, 68, 40,
 70, 71, 0, 0, 42, 52, 50, 9,
 10, 43, 43, 73, 74, 0, 47, 75,
 77, 0, 0, 48, 78, 79, 9, 80,
 57, 81, 30, 0, 0, 71, 82, 84,
 0, 0, 72, 7, 8, 9, 85, 73,
 87, 82, 0, 0, 74, 7, 89, 9,
 85, 75, 91, 93, 95, 0, 76, 82,
 96, 0, 0, 77, 60, 98, 27, 100,
 78, 101, 98, 27, 100, 79, 70, 71,
 0, 0, 80, 102, 103, 0, 0, 98,
 105, 0, 0, 0, 99, 105, 0, 0,
 0, 102, 108, 27, 110, 0, 103, 111,
 27, 112, 0, 104, 27, 28, 111, 0,
 105, 113, 115, 116, 32, 106, 118, 119,
 27, 112, 107, 120, 121, 0, 0, 108,
 27, 28, 67, 0, 127, 122, 0, 0,
 0
 CONSTINTEGERARRAY LETT(0: 124)=0,C 
 X'30222B00',X'25D60B13',X'13EF9000',X'4CB40000',
 X'52E91940',X'4EE9A0D0',X'382D2800',X'39F40000',
 X'25C00000',X'171094E7',X'38000000',X'25D60B13',
 X'10000000',X'582CA97F',X'3133A000',X'40320B4B',
 X'50B20000',X'4E051A4D',X'2461A25F',X'38000000',
 X'25C37CA5',X'14746640',X'4E051A4D',X'24A40000',
 X'04632CE7',X'244C2800',X'51EF0000',X'342EC800',
 X'15C49800',X'35339A5D',X'1C000000',X'424F1949',
 X'56450000',X'5E4F71C0',X'39E00000',X'3CC00000',
 X'4EA298E5',X'26149800',X'40320B4B',X'50B29800',
 X'40320B4B',X'52491800',X'06520E40',X'112D2BA7',
 X'25EE0000',X'582C4900',X'0474A858',X'40B26A69',
 X'50A40000',X'58324845',X'30A00000',X'09EF6143',
 X'38000000',X'19F20000',X'25C37CA5',X'14740000',
 X'11360000',X'3E05905D',X'12600000',X'25D429CB',
 X'48000000',X'31E30B00',X'09F57100',X'30A6A403',
 X'4A9F6267',X'50000000',X'30B62B26',X'112D2BA7',
 X'25EE9800',X'10A36380',X'35338303',X'0CA40000',
 X'25D3490A',X'3EB40000',X'258C29C3',X'30000000',
 X'15932800',X'4EA20000',X'0D019000',X'4E8D7500',
 X'08A74B80',X'55C118CB',X'4281130A',X'4F2D13D8',
 X'1123A25F',X'3832C800',X'4EA298E5',X'26140000',
 X'05922849',X'64000000',X'4E15925F',X'56600000',
 X'10A34B43',X'30000000',X'41E97500',X'17107B8B',
 X'3A800000',X'0DEE9D03',X'3A800000',X'30323940',
 X'48A16000',X'53302800',X'35336869',X'0D000000',
 X'04849167',X'4C224B13',X'53200000',X'5DF25993',
 X'30A00000',X'4DA16300',X'382D2CC0',X'31EE3800',
 X'424F3C83',X'34000000',X'5D344000',X'17142C9D',
 X'05800000',X'4E924B8E',X'0DEE9D00',X'066C0000',
 X'15B0A640',X'4CA5F859',X'1DECFB43',X'3AA16000'
 
 INTEGER I,J,K,M,Q,S
 PRINTSTRING(" (")
 I=-4
 UNTIL N=WORD(I) OR I= 261 THEN I=I+5
 CYCLE J=1,1,4
 K=WORD(I+J)
 IF K=0 THEN EXIT 
 SPACE UNLESS J=1
 UNTIL M&1=0 CYCLE 
 M=LETT(K); S=26
 UNTIL S<0 CYCLE 
 Q=M>>S&31; 
 IF Q=31 THEN Q=-32
 IF Q¬=0 THEN PRINT SYMBOL(Q+64)
 S=S-5
 REPEAT 
 K=K+1
 REPEAT 
 REPEAT 
 PRINTSTRING(") ")
 END 
ROUTINE FAULT(INTEGER N, FNAME)
INTEGER I, J, QP
 QP=Q
 NEWLINE
 IF VMEB=YES THEN FAULTMK(2); ! IDENTIFY ERROR MESSAGE
 IF N=100 THEN START 
 WHILE CCLINES(LINE+1)<=QMAX THEN LINE=LINE+1
 PRINTSTRING("* FAILED TO ANALYSE LINE ")
 WRITE(LINE, 2)
 IF FNAME#0 THEN MESSAGE(FNAME+70)
 NEWLINE; SPACES(5)
 FAULTY=FAULTY+1
 T=0; J=0; S=0
 UNTIL (J=';' AND Q>QMAX) OR Q=LENGTH OR C 
 (CC(Q)='E'+128 AND CC(Q+1)='N'+128 AND C 
 CC(Q+2)='D'+128) OR (CC(Q)='B'+128 AND C 
 CC(Q+1)='E'+128 AND CC(Q+2)='G'+128 AND CC(Q+3)= C 
 'I'+128 AND CC(Q+4)='N'+128 AND Q>QMAX)CYCLE 
 I=J; J=CC(Q)
 IF J>128 AND I<128 START 
 SPACE
 PRINTSYMBOL(KYCHAR1)
 T=T+2
 FINISH 
 IF I>128 AND J<128 START 
 PRINTSYMBOL(KYCHAR2)
 T=T+1
 FINISH 
 T=T+1
 IF Q=QMAX THEN START 
 S=T
 IF S>=115 THEN PRINTSYMBOL('!')
 FINISH 
 PRINT SYMBOL(J)
 Q=Q+1
 REPEAT 
 IF I>128 THEN PRINTSYMBOL(KYCHAR2) AND T=T+1
 IF Q=QMAX THEN S=T+1; ! CASE OF POINTER AT END
!
 IF S<115 THEN START 
 NEWLINE; SPACES(S+4)
 PRINT SYMBOL('!')
 FINISH 
 NEWLINE
 FINISH ELSE START 
 PRINTSTRING("*"); WRITE(LINE, 4)
 I=3; I=3*LEVEL IF LIST=0; SPACES(I)
 PARMOPT=1; FAULTY=FAULTY+1
 INHCODE=1; ! STOP GENERATING CODE
 PRINTSTRING("FAULT"); WRITE(N, 2)
 MESSAGE(N)
 IF N>100 THEN START 
 PRINTSTRING(" DISASTER
")
 STOP 
 FINISH 
 PRINTNAME(FNAME) UNLESS FNAME=0
 FINISH 
 IF VMEB=YES THEN START 
 NEWLINE
 FAULTMK(1); ! ENDOFERROR MESSAGE
 FINISH ELSE START 
 IF TTOPUT>=0 THEN START 
 Q=QP
 SELECT OUTPUT(TTOPUT)
 TTOPUT=TTOPUT!X'80000000'
 FAULT(N, FNAME)
 FAULTY=FAULTY-1
 NEWLINE
 SELECT OUTPUT(82)
 TTOPUT=TTOPUT&X'FFFF'
 FINISH 
 FINISH 
END 
ROUTINE WARN(INTEGER N,V)
CONSTSTRING (23)ARRAY MESS(1:5)=' KEYWORD IN COMMENT',
 ' NAME ? NOT USED ',
 ' LAB ? PASSED BY NAME!',
 ' DUMMY STMNT COMPILED',
 ' STRING CNST TRUNCATED'
 STRING (30) T; STRING (120) S
 IF MESS(N)->S.("?").T THEN S=S.STRING(DICTBASE+WRD(V)) C 
 .T ELSE S=MESS(N)
 PRINTSTRING("
? WARNING :- ".S." AT LINE NO")
 WRITE(LINE,1)
END 
ROUTINE PRINTNAME(INTEGER N)
INTEGER V, K
 SPACE; V=WRD(N)
 K=BYTEINTEGER(DICTBASE+V)
 IF K=0 THEN PRINTSTRING('???') ELSE C 
 PRINTSTRING(STRING(DICTBASE+V))
 END 
ROUTINE PRHEX(INTEGER VALUE, PLACES)
CONSTBYTEINTEGERARRAY HEX(0:15)='0','1','2','3','4',
 '5','6','7','8','9','A','B','C','D','E','F'
INTEGER I
 CYCLE I=PLACES<<2-4, -4, 0
 PRINT SYMBOL(HEX(VALUE>>I&15))
 REPEAT 
END 
INTEGERFN MORE SPACE
!***********************************************************************
!* FORMATS UP SOME MORE OF THE ASL *
!***********************************************************************
INTEGER I,N
 N=ASL CUR BTM-1
 ASL CUR BTM=ASL CUR BTM-(NNAMES+1)//8
 IF ASL CUR BTM<=1 THEN ASL CUR BTM=1
 CONST LIMIT=4*ASL CUR BTM-8
 IF ASL CUR BTM>=N OR CONST PTR>CONST LIMIT THEN FAULT(107,0)
 CYCLE I=ASL CUR BTM,1,N-1
 ASLIST(I+1)_LINK=I
 REPEAT 
 ASLIST(ASL CUR BTM)_LINK=0
 ASL=N; RESULT =N
END 
ROUTINE PUSH(INTEGERNAME CELL, INTEGER S1, S2, S3)
!***********************************************************************
!* PUSH A CELL CONTAINING THE 3 STREAMS OF INFORMATION GIVEN *
!* ONTO THE TOP OF THE LIST POINTED AT BY CELL. *
!***********************************************************************
RECORDNAME LCELL(LISTF)
INTEGER I
 I=ASL
 IF I=0 THEN I=MORE SPACE
 IF INCLUDE HANDCODE=NO THEN START 
 LCELL==ASLIST(I)
 ASL=LCELL_LINK
 LCELL_LINK=CELL
 CELL=I
 LCELL_S1=S1
 LCELL_S2=S2
 LCELL_S3=S3
 FINISH ELSE START 
 *LB_I
 *MYB_16
 *ADB_ASLIST+4
 *LCT_B 
 *LSS_(CTB +3)
 *ST_ASL
 *LB_I
 *LSS_(CELL)
 *STB_(DR )
 *LUH_S3
 *LUH_S1
 *ST_(CTB +0)
 FINISH 
END 
ROUTINE POP(INTEGERNAME CELL, S1, S2, S3)
!***********************************************************************
!* COPY THE INFORMATION FROM THE TOP CELL OF LIST 'CELL' INTO *
!* S1,S2&S3 AND THEN POP THE LIST UP 1 CELL. EMPTYLIST GIVE -1S*
!***********************************************************************
RECORDNAME LCELL(LISTF)
INTEGER I
 IF INCLUDE HANDCODE = NO THEN START 
 I=CELL
 LCELL==ASLIST(I)
 S1=LCELL_S1
 S2=LCELL_S2
 S3=LCELL_S3
 IF I# 0 THEN START 
 CELL=LCELL_LINK
 LCELL_LINK=ASL
 ASL=I
 FINISH 
 FINISH ELSE START 
 *LB_(CELL)
 *STB_I
 *MYB_16
 *ADB_ASLIST+4
 *LCT_B 
 *LSD_(CTB +0)
 *STUH_(S1)
 *LB_I
 *ST_(S2)
 *LSD_(CTB +2)
 *STUH_(S3)
 *JAT_12,<END>
 *ST_(CELL)
 *LSS_ASL
 *ST_(CTB +3)
 *STB_ASL
 FINISH 
END:
END 
 ROUTINE BINSERT(INTEGERNAME TOP,BOT,INTEGER S1,S2,S3)
!***********************************************************************
!* INSERT A CELL AT THE BOTTOM OF A LIST *
!* UPDATING TOP AND BOTTOM POINTERS APPROPIATELY *
!***********************************************************************
INTEGER I
RECORDNAME LCELL(LISTF)
 I=ASL
 IF I=0 THEN I=MORE SPACE
 LCELL==ASLIST(I)
 ASL=LCELL_LINK
 LCELL_S1=S1; LCELL_S2=S2
 LCELL_S3=S3; LCELL_LINK=0
 J=BOT
 IF J=0 THEN BOT=I AND TOP=BOT ELSE START 
 ASLIST(J)_LINK=I
 BOT=I
 FINISH 
END 
!%ROUTINE REPLACE123(%INTEGER CELL,S1,S2,S3)
! ASLIST(CELL)_S1=S1
! ASLIST(CELL)_S2=S2
! ASLIST(CELL)_S3=S3
!%END
ROUTINE MLINK(INTEGERNAME CELL)
 CELL=ASLIST(CELL)_LINK
END 
INTEGERFN FIND(INTEGER LAB, LIST)
!***********************************************************************
!* THIS FUNCTION SEARCHES LIST 'LIST' FOR LAB IN STREAM2 AND *
!* RETURNS THE CORRESPONDING CELL NO.IT USED FOR MORE THAN *
!* SCANNING LABEL LISTS. *
!***********************************************************************
 WHILE LIST#0 CYCLE 
 RESULT =LIST IF LAB=ASLIST(LIST)_S2
 LIST=ASLIST(LIST)_LINK
 REPEAT 
 RESULT =-1
END 
!%INTEGERFN FIND3(%INTEGER S3, LIST)
!!***********************************************************************
!!* SEARCHES LIST FOR S3 IN STREAM 3 *
!!* RETURNS CELL NO AS RESULT *
!!***********************************************************************
! %WHILE LIST#0 %CYCLE
! %RESULT=LIST %IF S3=ASLIST(LIST)_S3
! LIST=ASLIST(LIST)_LINK
! %REPEAT
! %RESULT=-1
!%END
ROUTINE FROM123(INTEGER CELL, INTEGERNAME S1, S2, S3)
!***********************************************************************
!* ALL THE FROMS RETURN INFO FROM CELLS OF A LIST WITHOUT *
!* AFFECTING THE LIST IN ANY WAY. *
!***********************************************************************
RECORDNAME LCELL(LISTF)
 LCELL==ASLIST(CELL)
 S1=LCELL_S1
 S2=LCELL_S2
 S3=LCELL_S3
END 
ROUTINE CLEAR LIST(INTEGERNAME OPHEAD)
!***********************************************************************
!* THROW AWAY A COMPLETE LIST (MAY BE NULL!) *
!***********************************************************************
INTEGER I, J
 I=OPHEAD; J=I
 WHILE I#0 THEN J=I AND I=ASLIST(J)_LINK
 IF J#0 START 
 ASLIST(J)_LINK=ASL
 ASL=OPHEAD; OPHEAD=0
 FINISH 
END 
!%ROUTINE CONCAT(%INTEGERNAME LIST1, LIST2)
!!***********************************************************************
!!* ADDS LIST2 TO BOTTOM OF LIST1 *
!!***********************************************************************
!%INTEGER I,J
! I=LIST1; J=I
! %WHILE I#0 %THEN J=I %AND I=ASLIST(J)_LINK
! %IF J=0 %THEN LIST1=LIST2 %ELSE ASLIST(J)_LINK=LIST2
! LIST2=0
!%END
!%ROUTINE RETURN LIST(%INTEGERNAME TOP,BOT)
!!***********************************************************************
!!* RETURN A WHOLE LIST TO ASL *
!!***********************************************************************
!%INTEGER CELL,J
! %IF TOP#0 %START
!! CELL=TOP
!! %WHILE CELL#0 %THEN J=CELL %AND CELL=ASLIST(CELL)_LINK
!! ABORT %IF J#BOT
! CELL=ASL
! ASL=TOP
! ASLIST(BOT)_LINK=CELL
! TOP=0
! %FINISH
!%END
ENDOFPROGRAM 


AltStyle によって変換されたページ (->オリジナル) /