!
! 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