MAINEP ICL9CEZIMP TRUSTEDPROGRAM BEGIN CONSTINTEGER RELEASE=10 CONSTINTEGER YES=1,NO=0 CONSTINTEGER USE IMP=NO CONSTINTEGER VMEB=NO CONSTSTRING(9) LADATE="28 Jan 81"; ! LAST ALTERED INTEGER I, J, K ! PRODUCED BY OLDPS FROM NRIMPPS8 ON 16/12/80 CONSTBYTEINTEGERARRAY CLETT(0: 500)= 1, 43, 1, 45, 1, 40, 1, 41, 1, 44, 2, 201, 198, 6, 213, 206, 204, 197, 211, 211, 5, 215, 200, 201, 204, 197, 5, 213, 206, 212, 201, 204, 3, 198, 207, 210, 1, 61, 4, 210, 197, 193, 204, 7, 201, 206, 212, 197, 199, 197, 210, 8, 204, 207, 206, 199, 210, 197, 193, 204, 4, 204, 207, 206, 199, 11, 194, 217, 212, 197, 201, 206, 212, 197, 199, 197, 210, 6, 211, 212, 210, 201, 206, 199, 11, 200, 193, 204, 198, 201, 206, 212, 197, 199, 197, 210, 7, 210, 207, 213, 212, 201, 206, 197, 2, 198, 206, 3, 205, 193, 208, 8, 198, 213, 206, 195, 212, 201, 207, 206, 6, 210, 197, 195, 207, 210, 196, 4, 206, 193, 205, 197, 5, 193, 210, 210, 193, 217, 9, 193, 210, 210, 193, 217, 206, 193, 205, 197, 9, 207, 198, 208, 210, 207, 199, 210, 193, 205, 6, 207, 198, 198, 201, 204, 197, 6, 207, 198, 204, 201, 211, 212, 6, 198, 207, 210, 205, 193, 212, 4, 211, 208, 197, 195, 3, 206, 207, 212, 3, 193, 206, 196, 2, 207, 210, 1, 58, 6, 206, 207, 210, 205, 193, 204, 3, 207, 215, 206, 8, 197, 216, 212, 197, 210, 206, 193, 204, 9, 197, 216, 212, 210, 201, 206, 211, 201, 195, 8, 195, 207, 206, 211, 212, 193, 206, 212, 5, 195, 207, 206, 211, 212, 5, 197, 214, 197, 206, 212, 5, 211, 212, 193, 210, 212, 9, 212, 200, 197, 206, 211, 212, 193, 210, 212, 4, 212, 200, 197, 206, 9, 197, 204, 211, 197, 211, 212, 193, 210, 212, 4, 197, 204, 211, 197, 1, 95, 6, 211, 217, 211, 212, 197, 205, 7, 196, 217, 206, 193, 205, 201, 195, 2, 42, 61, 1, 42, 4, 80, 85, 84, 95, 5, 67, 78, 79, 80, 95, 2, 204, 61, 1, 60, 1, 62, 4, 40, 196, 210, 43, 2, 196, 210, 1, 194, 3, 212, 207, 211, 3, 204, 206, 194, 3, 216, 206, 194, 2, 208, 195, 3, 195, 212, 194, 2, 45, 62, 6, 210, 197, 212, 213, 210, 206, 6, 210, 197, 211, 213, 204, 212, 7, 205, 207, 206, 201, 212, 207, 210, 4, 211, 212, 207, 208, 6, 211, 201, 199, 206, 193, 204, 4, 197, 216, 201, 212, 8, 195, 207, 206, 212, 201, 206, 213, 197, 6, 198, 201, 206, 201, 211, 200, 5, 195, 217, 195, 204, 197, 6, 210, 197, 208, 197, 193, 212, 3, 197, 206, 196, 5, 210, 197, 193, 204, 211, 5, 194, 197, 199, 201, 206, 2, 207, 206, 6, 211, 215, 201, 212, 195, 200, 4, 204, 201, 211, 212, 7, 211, 208, 197, 195, 201, 193, 204, 14, 212, 210, 213, 211, 212, 197, 196, 208, 210, 207, 199, 210, 193, 205, 6, 205, 193, 201, 206, 197, 208, 7, 195, 207, 206, 212, 210, 207, 204, 7, 201, 206, 195, 204, 213, 196, 197; CONSTINTEGERARRAY SYMBOL(1300: 2213)= 1307, 1303, 0, 1305, 2, 1307, 1000, 1319, 1312, 1001, 1357, 1824, 1315, 1003, 1020, 1319, 4, 1336, 6, 1329, 1323, 1001, 1014, 1325, 1003, 1329, 4, 1329, 6, 1336, 1336, 1010, 1028, 1319, 1011, 1350, 1343, 1343, 1010, 1028, 1307, 1011, 1343, 1350, 1348, 1026, 1307, 999, 1350, 1000, 1357, 1355, 1026, 1319, 999, 1357, 1000, 1365, 1363, 4, 1336, 1365, 6, 1365, 1000, 1372, 1370, 8, 1336, 999, 1372, 1000, 1377, 1375, 10, 1377, 13, 1401, 1384, 20, 1010, 1542, 1562, 1011, 1390, 26, 1010, 1542, 1562, 1011, 1401, 32, 1010, 1001, 36, 1336, 8, 1336, 8, 1336, 1011, 1408, 1406, 8, 1001, 999, 1408, 1000, 1415, 1411, 38, 1413, 43, 1415, 51, 1430, 1418, 43, 1420, 38, 1423, 60, 1408, 1425, 65, 1428, 77, 1925, 1430, 84, 1437, 1433, 96, 1437, 1031, 1415, 1437, 1444, 1440, 104, 1442, 107, 1444, 111, 1466, 1450, 1415, 1476, 1001, 1401, 1456, 120, 1466, 127, 1001, 1401, 1462, 1430, 1471, 1001, 1401, 1483, 1466, 127, 1001, 1401, 1471, 1469, 132, 1471, 1000, 1476, 1474, 127, 1476, 1000, 1483, 1479, 138, 1481, 127, 1483, 1000, 1493, 1491, 4, 1010, 1444, 1011, 1493, 6, 1493, 1000, 1502, 1500, 1030, 1010, 1444, 1011, 999, 1502, 1000, 1513, 1506, 148, 1016, 1508, 158, 1511, 165, 1018, 1513, 1016, 1518, 1516, 172, 1518, 1000, 1542, 1526, 172, 1001, 4, 1876, 1869, 6, 1535, 179, 1010, 1001, 1818, 1011, 4, 1001, 6, 1542, 1010, 1615, 1011, 4, 1001, 6, 1556, 1548, 1336, 1032, 1336, 1556, 1553, 4, 1542, 1562, 6, 1556, 184, 1542, 1562, 1560, 1037, 1336, 1562, 1000, 1573, 1567, 188, 1542, 1573, 1571, 192, 1542, 1580, 1573, 1000, 1580, 1578, 188, 1542, 999, 1580, 1000, 1587, 1585, 192, 1542, 999, 1587, 1000, 1595, 1591, 1033, 1336, 1593, 195, 1595, 1000, 1601, 1599, 179, 1008, 1601, 1015, 1606, 1604, 60, 1606, 197, 1615, 1613, 8, 1336, 195, 1336, 1606, 1615, 1000, 1624, 1620, 1476, 1001, 1401, 1624, 132, 1513, 1624, 1630, 1630, 1001, 1401, 1832, 1630, 1636, 1634, 8, 1624, 1636, 1000, 1652, 1646, 1476, 1010, 1001, 1401, 1840, 1011, 1652, 1006, 1652, 132, 1513, 1001, 1832, 1701, 1663, 1661, 8, 1010, 1001, 1401, 1840, 1011, 1652, 1663, 1000, 1674, 1666, 204, 1668, 208, 1670, 217, 1672, 227, 1674, 236, 1701, 1678, 1415, 1636, 1689, 120, 1476, 1010, 1001, 1401, 1011, 4, 1001, 6, 1006, 1701, 120, 132, 1513, 1010, 1001, 1832, 1011, 4, 1001, 6, 1006, 1711, 1709, 36, 1028, 1319, 1350, 1722, 1711, 1711, 1000, 1722, 1720, 8, 1012, 1028, 1319, 1350, 1722, 999, 1722, 1000, 1731, 1729, 4, 1028, 1319, 1350, 6, 1731, 1000, 1738, 1736, 8, 1009, 999, 1738, 1000, 1743, 1741, 242, 1743, 1000, 1749, 1747, 8, 1336, 1749, 1000, 1762, 1760, 8, 1001, 1401, 4, 1336, 195, 1336, 6, 999, 1762, 1000, 1769, 1767, 26, 1542, 1562, 1769, 1000, 1782, 1772, 1019, 1774, 1006, 1779, 1372, 1542, 1562, 1006, 1782, 1377, 1006, 1795, 1786, 248, 1034, 1789, 254, 1034, 1795, 264, 1010, 2060, 1011, 1801, 1801, 1799, 188, 2060, 1801, 1000, 1818, 1805, 269, 1034, 1813, 279, 1372, 1010, 1542, 1562, 1011, 1782, 1816, 279, 2060, 1818, 1000, 1824, 1822, 284, 1001, 1824, 1000, 1832, 1830, 284, 1001, 1357, 1824, 1832, 1000, 1840, 1840, 4, 1336, 195, 1336, 1606, 6, 1848, 1846, 36, 1028, 1319, 1350, 1848, 1000, 1858, 1852, 286, 1013, 1854, 208, 1856, 293, 1858, 1000, 1869, 1867, 1001, 36, 1336, 8, 1336, 8, 1336, 1869, 1000, 1876, 1874, 8, 1876, 999, 1876, 1000, 1916, 1882, 1415, 1476, 1001, 1401, 1889, 1415, 132, 1001, 1401, 1832, 1916, 1895, 120, 1466, 127, 1001, 1401, 1904, 120, 1010, 1001, 1401, 1011, 4, 1001, 6, 1916, 120, 132, 1010, 1001, 1401, 1832, 1916, 1011, 4, 1001, 6, 1925, 1923, 8, 1001, 1401, 1832, 999, 1925, 1000, 1932, 1930, 4, 1009, 6, 1932, 1000, 1950, 1936, 301, 1001, 1939, 304, 1001, 1942, 306, 1002, 1945, 1022, 1950, 1950, 311, 1009, 8, 1009, 1964, 1954, 1023, 1964, 1959, 1024, 317, 2003, 2008, 1964, 1025, 1005, 8, 1987, 1987, 1969, 320, 1001, 322, 1971, 2036, 1976, 4, 2036, 2025, 6, 1980, 324, 2036, 6, 1985, 4, 329, 2025, 6, 1987, 332, 2003, 1992, 320, 1001, 322, 1994, 2036, 1999, 4, 329, 2025, 6, 2003, 324, 1005, 6, 2008, 2006, 329, 2008, 1005, 2016, 2014, 8, 1005, 8, 1005, 2016, 1000, 2025, 2020, 0, 1005, 2023, 2, 1005, 2025, 1000, 2031, 2029, 0, 332, 2031, 1000, 2036, 2034, 36, 2036, 1000, 2051, 2041, 2031, 1300, 1003, 2044, 1001, 2016, 2049, 4, 2051, 2016, 6, 2051, 334, 2060, 2054, 338, 2056, 342, 2058, 346, 2060, 349, 2093, 2069, 1010, 1001, 1357, 1824, 1011, 1587, 1795, 2073, 353, 1001, 1357, 2075, 356, 2079, 363, 1033, 1336, 2082, 370, 1795, 2084, 378, 2089, 383, 1738, 1009, 1743, 2091, 390, 2093, 395, 2214, 2100, 1027, 1010, 2060, 1011, 1769, 2102, 1007, 2110, 1372, 1010, 1542, 1562, 1011, 1782, 1006, 2115, 404, 1035, 1801, 1006, 2120, 411, 1029, 1858, 1006, 2125, 417, 1036, 1762, 1006, 2130, 1377, 411, 1029, 1006, 2136, 1031, 1008, 1415, 1615, 1006, 2140, 424, 1502, 1006, 2144, 120, 1518, 1006, 2153, 1010, 1848, 1430, 1011, 1595, 1001, 1483, 1006, 2156, 1663, 1674, 2160, 428, 1601, 1006, 2164, 434, 1015, 1006, 2173, 440, 1021, 1738, 1009, 1731, 248, 1034, 1006, 2184, 443, 1001, 1401, 4, 1336, 195, 1336, 6, 1749, 1006, 2188, 450, 1006, 1017, 2193, 455, 127, 1001, 1006, 2197, 304, 1932, 1006, 2200, 463, 1006, 2204, 478, 1001, 1006, 2208, 485, 1003, 1006, 2212, 493, 1003, 1038, 2214, 1006; CONSTINTEGER SS= 2093 ! CONST BYTE INTEGER ARRAY I TO E TAB(0 : 127) = C X'40',X'40',X'40',X'40',X'40',X'40',X'40',X'40', X'40',X'40',X'15',X'40',X'0C',X'40',X'40',X'40', X'40',X'40',X'40',X'40',X'40',X'40',X'40',X'40', X'40',X'40',X'40',X'40',X'40',X'40',X'40',X'40', 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'5F',X'5A',X'6A',X'6D', X'7C',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'40',X'D0',X'40',X'40' CONSTINTEGERARRAY OPC(0:126)=0, M' JCC',M' JAT',M' JAF',0(4), M' VAL',M' CYD',M'INCA',M'MODD',M'PRCL',M' J',M' JLK',M'CALL', M' ADB',M' SBB',M'DEBJ',M' CPB',M' SIG',M' MYB',M' VMY',M'CPIB', M' LCT',M'MPSR',M'CPSR',M'STCT',M'EXIT',M'ESEX',M' OUT',M' ACT', M' SL',M'SLSS',M'SLSD',M'SLSQ',M' ST',M'STUH',M'STXN',M'IDLE', M' SLD',M' SLB',M'TDEC',M'INCT',M' STD',M' STB',M'STLN',M'STSF', M' L',M' LSS',M' LSD',M' LSQ',M'RRTC',M' LUH',M'RALN',M' ASF', M'LDRL',M' LDA',M'LDTB',M' LDB',M' LD',M' LB',M' LLN',M' LXN', M' TCH',M'ANDS',M' ORS',M'NEQS',M'EXPA',M' AND',M' OR',M' NEQ', M' PK',M' INS',M'SUPK',M' EXP',M'COMA',M' DDV',M'DRDV',M'DMDV', M'SWEQ',M'SWNE',M' CPS',M' TTR',M' FLT',M' IDV',M'IRDV',M'IMDV', M' MVL',M' MV',M'CHOV',M' COM',M' FIX',M' RDV',M'RRDV',M'RDVD', M' UAD',M' USB',M'URSB',M' UCP',M' USH',M' ROT',M' SHS',M' SHZ', M' DAD',M' DSB',M'DRSB',M' DCP',M' DSH',M' DMY',M'DMYD',M'CBIN', M' IAD',M' ISB',M'IRSB',M' ICP',M' ISH',M' IMY',M'IMYD',M'CDEC', M' RAD',M' RSB',M'RRSB',M' RCP',M' RSC',M' RMY',M'RMYD'; CONSTBYTEINTEGERARRAY ONE CASE(0 : 127) = C 0, 1, 2, 3, 4, 5, 6, 7, 8, 9,10,11,12,13,14,15, 16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31, 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,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,123,124,125,126,127; CONSTINTEGERARRAY TSNAME (0:62)=X'1000'(8), X'1001',X'1000'(5),X'1001',X'1062',X'1001'(2),X'1062', X'1000'(2),X'52',X'51',X'62',X'1062'(7), X'1000',X'31',X'51',X'1062'(2),X'31',X'1000', X'51',X'62',X'1000'(2),X'35',X'1000',X'1035', X'31',X'35',X'1035',X'33',0,X'1000',X'31',X'52',X'51', X'61',X'72',X'61',X'72',X'51',X'62',X'1051',X'41', X'1000'; ! OWNINTEGERARRAY FIXED GLA(0:11)=0, X'50000000',0(2),-1,0,0(6); CONSTBYTEINTEGERARRAY BYTES(0:7)=0(3),1,2,4,8,16; CONSTBYTEINTEGERARRAY TRTAB(0:255)=0(48), 1(10),0(7),2(26),0(6),2(26),0(5),0(128) CONSTINTEGER MAXLEVELS=31,CONCOP=13,FIXEDGLALEN=48 CONSTINTEGER JOBBERBIT=X'40000000'; ! SET IN JOBBER MODE CONSTINTEGER CEBIT=1; ! SET IN COMPILER ENVIRONMENT CONSTINTEGER MAXDICT=X'100'; ! SET FOR MAX OF EVERYTHING ! ! 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',OUT=X'3C',CPSR=X'34' 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',SLD=X'50' 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' 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',IMYD=X'EC',IDV=X'AA' CONSTINTEGER RAD=X'F0',RSB=X'F2',RRSB=X'F4',FLT=X'A8',RRDV=X'BC', C RSC=X'F8',FIX=X'B8',RDV=X'BA',RDDV=X'BE',RMYD=X'FC', C RMY=X'FA' ! CONSTINTEGER MVL=X'B0',MV=X'B2',SWEQ=X'A0',SWNE=X'A2',CPS=X'A4' ! ! DEFINE SOME MNEMONICS FOR THE VISIBLE REGISTERS (XCEPT LNB) ! 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(8)MDEP="S#NDIAG" CONSTSTRING(8)IOCPEP="S#IOCP"; ! EP FOR IOCP CONSTSTRING(11)AUXSTEP="ICL9CEAUXST"; ! DATA REF FOR INDIRECT AUX ST CONSTINTEGER SNPT=X'1006'; ! SPECIALNAME PTYPE CONSTINTEGER COMMALT=2,ENDALT=9,UNASSPAT=X'81818181',DECALT=8 ! INTEGER DICTBASE, CONSTPTR, CONSTBTM, DFHEAD, CONSTHOLE, WKFILEAD, C WKFILEK, DUMMYFORMAT, P1SIZE, LEVELINF, IOCPDISP, PARMBITS1, C PARMBITS2,PARMLET ! INTEGER ASL, NNAMES, ARSIZE, CABUF, PPCURR, CONSTLIMIT, OLDLINE, C LINE, LENGTH, NEXTP, SNUM, RLEVEL, NMAX, USTPTR, PLABEL,C LEVEL, CA, LASTNAME, CDCOUNT, ASL CUR BTM, PARMDYNAMIC ! INTEGER FAULTY, HIT, INHCODE, IMPS, TTOPUT, LIST, PARMDIAG, C WARNFLAG, PARMTRACE, PARMLINE, PARMOPT, CTYPE, DCOMP, C CPRMODE, PARMCHK, PARMARR, ALLLONG, PARMDBUG,C COMPILER, LAST INST, SMAP, STACK, AUXST, PARMY, BFFLAG ! INTEGER RBASE, N, FREE FORMAT, PARMPROF, EXITLAB, CONTLAB, C Q, R, S, NEST, FNAME, LDPTR, GLACA, GLACABUF, C GLACURR, CREFHEAD, SSTL, QMAX, STMTS, LASTAT, C FILE ADDR, FILE PTR, FILE END, FILE SIZE, LASTEND, C BIMSTR,STLIMIT,STRLINK,RECTB,ASL WARN,IHEAD ! INTEGER MAX ULAB, SFLABEL LONGREAL CVALUE, IMAX, CTIME STRING(31)MAINEP RECORDFORMAT LISTF(INTEGER S1,S2,S3,LINK) INTEGER LOGEPDISP,EXPEPDISP ! SYSTEMINTEGERMAPSPEC COMREG(INTEGER N) BEGIN FILE ADDR=COMREG(46); ! SOURCE FILE IF CLEAN PARMBITS1=COMREG(27) PARMBITS2=COMREG(28) WKFILEAD=COMREG(14) WKFILEK=INTEGER(WKFILEAD+8)>>10 IF FILE ADDR<=0 THEN FILESIZE=64000 AND FILE ADDR=0 ELSESTART FILE PTR=FILE ADDR+INTEGER(FILE ADDR+4) FILE END=FILE ADDR+INTEGER(FILE ADDR) FILE SIZE=INTEGER(FILE ADDR) FINISH NNAMES=255 IF FILESIZE>10000 THEN NNAMES=511 IF PARMBITS1&JOBBER BIT=0 START IF FILESIZE>32000 THEN NNAMES=1023 IF FILESIZE>256*1024 OR PARMBITS2&MAXDICT#0 OR C WKFILEK>512 THEN NNAMES=2047 FINISH ASL=3*NNAMES ASL=4095 IF ASL>4095 AND PARMBITS2&MAXDICT=0; ! STAY WITHIN 128K AUXSTACK ARSIZE=WKFILEK*768-300 END BYTEINTEGERARRAYFORMAT AF(0:ARSIZE) BYTEINTEGERARRAYNAME A RECORDARRAY ASLIST(0:ASL)(LISTF) INTEGERARRAY WORD, TAGS(0:NNAMES) INTEGERARRAY DVHEADS(0:12) INTEGERFNSPEC FROMAR4(INTEGER PTR) INTEGERFNSPEC FROMAR2(INTEGER PTR) ROUTINESPEC TOAR8(INTEGER PTR, LONGREAL VALUE) ROUTINESPEC TOAR4(INTEGER PTR, VALUE) ROUTINESPEC TOAR2(INTEGER PTR,VALUE) ROUTINESPEC WARN(INTEGER N,V) ROUTINESPEC FAULT2(INTEGER N,VAL,IDEN) ROUTINESPEC FAULT(INTEGER N, VALUE) STRINGFNSPEC PRINTNAME(INTEGER N) INTEGERFNSPEC MORE SPACE !%INTEGERFNSPEC NEWCELL ROUTINESPEC INSERTATEND(INTEGERNAME S, INTEGER A, B, C) ROUTINESPEC FROM12(INTEGER CELL, INTEGERNAME S1, S2) ROUTINESPEC FROM123(INTEGER CELL, INTEGERNAME S1, S2, S3) ROUTINESPEC POP(INTEGERNAME C, P, Q, R) ROUTINESPEC PUSH(INTEGERNAME C, INTEGER S1, S2, S3) INTEGERFNSPEC FIND(INTEGER LAB, LIST) ROUTINESPEC MLINK(INTEGERNAME CELL) ROUTINESPEC REPLACE1(INTEGER CELL, S1) ROUTINESPEC REPLACE2(INTEGER CELL, S2) ROUTINESPEC REPLACE3(INTEGER CELL,S3) ROUTINESPEC REPLACE123(INTEGER CELL,A1,A2,S3) INTEGERFNSPEC FROM2(INTEGER CELL) INTEGERFNSPEC FROM1(INTEGER CELL) INTEGERFNSPEC FROM3(INTEGER CELL) ROUTINESPEC BINSERT(INTEGERNAME T,B,INTEGER S1,S2,S3) ROUTINESPEC CLEARLIST(INTEGERNAME HEAD) STRING(255)FNSPEC MESSAGE(INTEGER N) SYSTEMROUTINESPEC LPUT(INTEGER A, B, C, D) SYSTEMLONGREALFNSPEC CPUTIME !*DELSTART SYSTEMROUTINESPEC NCODE(INTEGER START, FINISH, CA) ROUTINESPEC PRINTLIST(INTEGER HEAD) ROUTINESPEC PRHEX(INTEGER VALUE,PLACES) ROUTINESPEC CHECK ASL !*DELEND IF VMEB=NO THEN START SYSTEMROUTINESPEC CONSOURCE(STRING(31)FILE,INTEGERNAME AD) FINISH ! START OF COMPILATION A==ARRAY(WKFILE AD+256*WKFILEK, AF) BEGIN !*********************************************************************** !* THIS BLOCK INITIALISE THE COMPILER SCALARS AND ARRAYS * !* WAS ORIGINALLY ROUTINE 'INITIALISE'. * !* THE INITIALISATION OF THE CONSTANT LISTS WITH THE VALUES * !* IN PERM MAY BE OMITTED IN BATCH OR CUT-DOWN VERSIONS. * !*********************************************************************** ROUTINESPEC READ LINE(INTEGER MODE,CHAR) INTEGERFNSPEC COMPARE(INTEGER P) ROUTINESPEC PNAME(INTEGER MODE) ROUTINESPEC CONST(INTEGER MODE) ROUTINESPEC TEXTTEXT(INTEGER EBCDIC) INTEGER CCSIZE,DSIZE,NEXT,ATLINE1,STARSTART CCSIZE=1000; DSIZE=7*NNAMES INTEGERARRAY DISPLAY,SFS(0:MAXLEVELS) BYTEINTEGERARRAY TLINE(-60:161),CC(0:CCSIZE),LETT(0:DSIZE+20) LONGINTEGER ATL0,ASYM0 CONSTBYTEINTEGERARRAY ILETT(0: 500)= 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', 10,'S','K','I','P','S','Y','M','B','O', 'L', 10,'R','E','A','D','S','T','R','I','N','G', 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', 5,'W','R','I','T','E', 7,'N','E','W','P','A','G', 'E', 4,'A','D','D','R', 6,'A','R','C','S','I','N', 3,'I','N', 'T', 5,'I','N','T','P','T', 6,'F','R','A','C','P','T', 5,'P', 'R','I','N','T', 7,'P','R','I','N','T','F','L', 4,'R','E','A', 'L', 7,'I','N','T','E','G','E','R', 3,'M','O','D', 6,'A','R', 'C','C','O','S', 4,'S','Q','R','T', 3,'L','O','G', 3,'S','I', 'N', 3,'C','O','S', 3,'T','A','N', 3,'E','X','P', 11,'C','L', 'O','S','E','S','T','R','E','A','M', 11,'B','Y','T','E','I','N', 'T','E','G','E','R', 8,'E','V','E','N','T','I','N','F', 6,'R','A','D','I','U','S', 6,'A','R','C','T','A','N', 6,'L','E','N','G','T','H', 11,'P','R','I','N','T','S','T','R', 'I','N','G', 2,'N','L', 8,'L','O','N','G','R','E','A','L', 7, 'P','R','I','N','T','C','H', 6,'R','E','A','D','C','H', 6,'S', 'T','R','I','N','G', 8,'R','E','A','D','I','T','E','M', 8,'N', 'E','X','T','I','T','E','M', 6,'C','H','A','R','N','O', 8,'T', 'O','S','T','R','I','N','G', 10,'F','R','O','M','S','T','R','I', 'N','G', 6,'R','E','C','O','R','D', 5,'A','R','R','A','Y', 10, 'S','E','T','M','A','R','G','I','N','S',4,'I','M','O','D',2,'P', 'I',9,'E','V','E','N','T','L','I','N','E',11,'L','O','N','G', 'I','N','T','E','G','E','R',12,'L','O','N','G','L','O','N','G', 'R','E','A','L',9,'L','E','N','G','T','H','E','N','I', 9,'L','E','N','G','T','H','E','N','R', 8,'S','H','O','R','T','E','N','I', 8,'S','H','O','R','T','E','N','R', 6,'N','E','X','T','C','H', 11,'H','A','L','F','I','N','T','E','G','E','R', 8,'P','P','R','O','F','I','L','E',255; IMAX=(-1)>>1;PLABEL=24999 LETT(0)=0 ATLINE1=ADDR(TLINE(1)) INTEGER(ADDR(ATL0)+4)=ATLINE1-1 INTEGER(ADDR(ATL0))=X'18000100' INTEGER(ADDR(ASYM0))=X'28000C00' INTEGER(ADDR(ASYM0)+4)=ADDR(SYMBOL(1300))-4*1300 N=12; MAX ULAB=NNAMES+16384; ! LARGEST VALID USER LABEL GLACURR=0; GLACA=FIXEDGLALEN; GLACABUF=GLACA PARMOPT=1 ; PARMARR=1; LAST INST=0 PARMLINE=1; PARMTRACE=1; PARMDIAG=1 LIST=1; SFLABEL=20999; PARMCHK=1 EXITLAB=0; CONTLAB=0 CABUF=0; PPCURR=0; OLDLINE=0; COMPILER=0 RLEVEL=0; NMAX=0; USTPTR=0 LEVEL=0; CA=0; LASTAT=0 FAULTY=0; WARNFLAG=0; ALLLONG=0; INHCODE=0 DCOMP=0; BFFLAG=0; CPRMODE=0 NEXT=1; LDPTR=0 IOCPDISP=0; CREFHEAD=0; AUXST=0 RBASE=10; LOGEPDISP=0; EXPEPDISP=0; STRLINK=0 RECTB=0; IHEAD=0 SSTL=0; STMTS=1; SNUM=0; LEVELINF=0 CDCOUNT=0 BIMSTR=0 LOGEPDISP=0; EXPEPDISP=0 MAINEP="S#GO"; ! DEFAULT MAIN ENTRY DICTBASE=ADDR(LETT(0)) ! ! OPEN OBJECT FILE HERE BEFORE MORE PAGES OF COMPILER CODE ! ARE PAGED IN AND SUB-SYSTEM PAGES MOVE OUT ! LPUT(0,0,0,0) CTIME=CPUTIME I=COMREG(27) STLIMIT=X'1F000' IF I>>24&1#0 THEN STLIMIT=COMREG(48)-4096 IF I&2=2 THEN LIST=0 IF I&4=4 THEN PARMDIAG=0 IF I&X'800000'#0 THEN PARMLINE=0 IF I&16=16 THEN PARMCHK=0 IF I&32=32 THEN PARMARR=0 PARMPROF=(I>>15&1)!(I>>7&1); ! USE MAP OR PROFILE BIT PRO TEM PARMDYNAMIC=I>>20&1 PARMLET=I>>13&1 DCOMP=I>>14&1; ! PARM CODE OR D PARMDBUG=I>>18&1 IF I&64=64 THEN PARMTRACE=0 AND PARMDIAG=0 FREE FORMAT=I&X'80000' STACK=I>>3&1 SMAP=I>>26&1; ! USE PARMZ BIT FOR DUMPING WKFILE TTOPUT=COMREG(40) IF I&(1<<16)#0 THEN START PARMARR=0; PARMOPT=0 PARMLINE=0; PARMCHK=0; PARMDIAG=0 FINISH PARMTRACE=PARMTRACE!PARMOPT; ! ALLOW NOTRACE ONLY WITH OPT IMPS=I>>23&1; ! BIT SET IF IMPS REQUESTED IMPS=1; ! FOR TESTING NEWLINES(3); SPACES(14) PRINTSTRING("ERCC. Imp") IF IMPS#0 THEN PRINTSYMBOL('s') PRINTSTRING(" Compiler Release") WRITE(RELEASE,1) PRINTSTRING(" Version ".LADATE) NEWLINES(3) WRITE(NNAMES,5); WRITE(ASL,5) NEWLINE ASL WARN=0 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 CYCLE I=0,1,NNAMES WORD(I)=0; TAGS(I)=0; REPEAT CYCLE I=0,1,12 DVHEADS(I)=0 REPEAT ! ! NOW DECLARE THE SPECIAL NAMES WHICH ARE IN ARRAY ILETT. ! K=0; NEXT=1 I=ILETT(0) WHILE I<255 CYCLE CYCLE J=I,-1,1 CC(J)=ILETT(K+J) REPEAT CC(I+1)=';' R=2; Q=1; PNAME(1) PUSH(TAGS(LASTNAME),SNPT<<16!X'8000',0,SNUM<<16) SNUM=SNUM+1 K=K+I+1; I=ILETT(K) REPEAT ! COMREG(24)=16; ! RETURN CODE DUMMY FORMAT=0; ! DUMMY RECORD FORMAT DFHEAD=0 PUSH(DFHEAD,0,0,0) PUSH(DUMMY FORMAT,0,0,DFHEAD); ! FOR BETTER ERROR RECOVERY LINE=0; LENGTH=0; Q=1 R=1; LEVEL=1 CYCLE IF Q>=LENGTH THEN QMAX=1 AND READ LINE(0,0) WARNFLAG=0 STARSTART=R R=R+3 OLDLINE=LINE A(R)=LINE>>8 A(R+1)=LINE&255 R=R+2 IF COMPARE(SS)=0 THEN START FAULT(100,ADDR(CC(0))) R=STARSTART FINISH ELSE START FAULT(102, 0) IF R>ARSIZE IF A(STARSTART+5)=COMMALT THEN R=STARSTART ELSE START I=R-STARSTART A(STARSTART)=I>>16 A(STARSTART+1)=I>>8&255 A(STARSTART+2)=I&255 IF A(STARSTART+5)=DECALT AND LEVEL>1 THEN START IF SFS(LEVEL)=0 THEN START TO AR4(DISPLAY(LEVEL),STARSTART) DISPLAY(LEVEL)=STARSTART+6 FINISH ELSE A(STARSTART+6)=128; ! FLAG AS UNLINKED FINISH !*DELSTART IF SMAP#0 THEN START NEWLINE; WRITE(LINE, 5) WRITE(STARSTART,5); NEWLINE; J=0 CYCLE I=STARSTART, 1, R-1 WRITE(A(I), 5) J=J+1 IF J>=20 THEN NEWLINE AND J=0 REPEAT NEWLINE FINISH !*DELEND EXIT IF A(STARSTART+5)=ENDALT AND C 1<=A(STARSTART+6)<=2;! ENDOF PROG OR FILE IF LEVEL=0 THEN FAULT(14, 0) AND EXIT FINISH FINISH REPEAT TO AR8(R,0); R=R+8 IF R+NEXT>ARSIZE THEN FAULT(102,0) P1SIZE=R IF USE IMP=YES THEN START CYCLE I=0,1,NEXT A(R+I)=LETT(I) REPEAT FINISH ELSE START *LDTB_X'18000000' *LDB_NEXT *LDA_LETT+4 *CYD_0 *LDA_A+4 *INCA_R *MV_L=DR FINISH DICTBASE=ADDR(A(R)) R=R+NEXT+1 ->BEND ROUTINE READ LINE(INTEGER MODE,CHAR) ROUTINESPEC GET LINE INTEGER DEL, LL, LP LL=0; LP=0; Q=1 LENGTH=0; DEL=0 NEXT: IF USE IMP=YES THEN START LP=LP+1 IF LP>LL THEN GET LINE AND LP=1 I=TLINE(LP) IF MODE=0 THEN START IF I='%' THEN DEL=128 AND ->NEXT I=ONE CASE(I) IF 'A'<=I<='Z' THEN I=I!DEL ELSE START DEL=0 ->NEXT IF I=' ' FINISH LENGTH=LENGTH+1 CC(LENGTH)=I IF I='''' OR I=34 THEN MODE=1 AND CHAR=I FINISH ELSE START LENGTH=LENGTH+1 CC(LENGTH)=I IF I=CHAR THEN MODE=0 FINISH ->NEXT UNLESS I=NL FINISH ELSE START *LB_LP *ADB_1 *CPB_LL *JCC_12,<RLL1> GET LINE *LB_1 RLL1: *STB_LP *LB_(ATL0+B) *LSS_MODE *JAF_4,<RLL2> *CPB_37; !'%' *JCC_7,<RLL3> *L_128 *ST_DEL *J_<NEXT> RLL3: *LSS_(ONE CASE+B); ! LOWER CASE TO UPPER *ICP_65; !'A' *JCC_4,<RLL4> *ICP_90; !'Z' *JCC_2,<RLL4> *OR_DEL *J_<RLL5> RLL4: *LB_0 *STB_DEL *ICP_32; !' ' *JCC_8,<NEXT> RLL5: *LB_LENGTH *ADB_1 *STB_LENGTH *ST_(CC+B) *ICP_39; !'''' *JCC_8,<RLL6> *ICP_34; !'"' *JCC_7,<RLL7> RLL6: *ST_CHAR *LB_1 *STB_MODE RLL7: *ICP_10 *JCC_7,<NEXT> *J_<RLL8> RLL2: *LSS_B *LB_LENGTH *ADB_1 *STB_LENGTH *ST_(CC+B) *ICP_CHAR *JCC_7,<RLL9> *LB_0 *STB_MODE RLL9: *ICP_10 *JCC_7,<NEXT> RLL8: FINISH IF CC(LENGTH-1)='C'+128 THEN LENGTH=LENGTH-2 AND ->NEXT FAULT(101,0) IF LENGTH>CCSIZE RETURN ROUTINE GET LINE SYSTEMROUTINESPEC IOCP(INTEGER A,B) 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); INTEGER K LL=0 IF FILE ADDR=0 THEN START; ! SOURCE NOT A 'CLEAN' FILE UNTIL K=NL CYCLE READ SYMBOL(K) TLINE(LL+1)=ITOI(K) LL=LL+1 REPEAT FINISH ELSE START IF FILEPTR>=FILE END START IF IHEAD#0 THEN POP(IHEAD,FILEADDR,FILEPTR,FILEEND) C AND GETLINE AND RETURN SIGNAL EVENT 9,1 FINISH IF USE IMP=NO 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_ATLINE1 *MV_L=DR,0,0 *LDA_ATLINE1; *LDTB_X'18000000' *LDB_LL *LSS_ITOI+4; *LUH_X'180000FF' *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 TLINE(LL+1)=ITOI(K) LL=LL+1 REPEAT OLIST: FINISH ! %IF MODE=0 %AND LL=1 %THEN GET LINE %AND %RETURN ! LINE=LINE+1 %UNLESS MODE=0 %AND LENGTH>0 LINE=LINE+1; ! COUNT ALL LINES IF LIST#0 THEN START IF MODE=0 AND LENGTH>0 THEN C PRINTSTRING(" C") ELSE WRITE(LINE, 5) ! SPACES(8) CYCLE K=-7,1,0 TLINE(K)=' ' REPEAT IF MODE#0 THEN TLINE(-7)=M'"' TLINE(-8)=LL+8 IOCP(15,ADDR(TLINE(-8))) FINISH IF FREE FORMAT=0 AND LL>73 THEN TLINE(73)=10 AND LL=73 END END INTEGERFN COMPARE(INTEGER P) INTEGER I, J, ITEM, RA, RL, RP, RQ, RR, RS, MARKER, SSL, ALT, PP OWNINTEGER SAVECOMP; ! FOR CHECKING DSIDED CONDS SWITCH BIP(999:1038) IF USE IMP=YES THEN START RP=SYMBOL(P) RL=LEVEL P=P+1 PP=P; ! ROUTINE REALLY STARTS HERE FINISH ELSE START *LB_P *JLK_2 *EXIT_-64 SUBENTRY: *LSS_(ASYM0+B) *LUH_LEVEL *ST_RL *ADB_1 *STB_P *STB_PP FINISH COMM: IF USE IMP=YES THEN START RQ=Q; ! RESET VALUES OF LINE&AR PTRS RR=R SSL=STRLINK; ! SAVE STRING LINK ALT=1; ! FIRST ALTERNATIVE TO BE TRIED RA=SYMBOL(P); ! RA TO NEXT PHRASE ALTERNATIVE RS=P FINISH ELSE START *LSD_Q *ST_RQ *LSS_1 *LUH_STRLINK *ST_SSL *LB_P *LSS_(ASYM0+B) *ST_RA *STB_RS FINISH UPR: R=R+1 SUCC: ! SUCCESS ON TO NEXT ITEM IF USE IMP=YES THEN START RS=RS+1; ! RS=NEXT ALTERNATIVE MEANS THAT ! THIS ALT HAS BEEN COMPLETED SO ! EXIT WITH HIT=1 IF RS=RA THEN ->FINI ITEM=SYMBOL(RS); ! NEXT BRICK IN THE CURRENT ALT IF ITEM<999 THEN ->LIT FINISH ELSE START *LB_RS *ADB_1 *CPB_RA *JCC_8,<FINI> *STB_RS *LB_(ASYM0+B) *CPB_999 *JCC_4,<LIT> *STB_ITEM FINISH IF ITEM<1300 THEN ->BIP(ITEM) ! BRICK IS A PHRASE TYPE IF USE IMP=YES THEN START IF COMPARE(ITEM)=0 THEN ->FAIL FINISH ELSE START *LSD_RA *SLSQ_RP *SLSQ_MARKER *ST_TOS *LB_ITEM *JLK_<SUBENTRY> *ST_B; ! RESULT=0 FOR FAIL *LSQ_TOS; *ST_MARKER *LSQ_TOS; *ST_RP *LSD_TOS; *ST_RA *JAT_12,<FAIL> FINISH ->SUCC LIT: ! BRICK IS LITERAL IF USE IMP=YES THEN START I=CC(Q); ! OBTAIN CURRENT CHARACTER ->FAIL UNLESS I=CLETT(ITEM+1) Q=Q+1 K=CLETT(ITEM)+ITEM ITEM=ITEM+2 WHILE ITEM<=K CYCLE ->FAIL UNLESS CC(Q)=CLETT(ITEM) Q=Q+1 ITEM=ITEM+1 REPEAT; ! CHECK IT WITH LITERAL DICT ENTRY FINISH ELSE START *LDB_(CLETT+B) *INCA_B *INCA_1 *LSS_Q *IAD_CC+4 *LUH_CC *CPS_L=DR,0,0 *JCC_7,<FAIL> *STUH_B *ISB_CC+4 *ST_Q FINISH ->SUCC; ! MATCHED SUCCESSFULLY FAIL: ! FAILURE - NOTE POSITION REACHD IF USE IMP=YES THEN START IF RA=RP THEN ->TFAIL; ! TOTAL FAILURE NO ALT TO TRY QMAX=Q IF Q>QMAX Q=RQ; ! RESET LINE AND A.R. POINTERS R=RR+1; ! AVOID GOING VIA UPR: STRLINK=SSL ALT=ALT+1; ! MOVE TO NEXT ALT OF PHRASE RS=RA RA=SYMBOL(RA) FINISH ELSE START *LB_RA *CPB_RP *JCC_8,<TFAIL> *LSS_Q *ICP_QMAX *JCC_12,<CPL1> *ST_QMAX CPL1: *LSD_RQ *IAD_1 *ST_Q *L_SSL *STUH_STRLINK *IAD_1 *ST_ALT *STB_RS *L_(ASYM0+B) *ST_RA FINISH ->SUCC TFAIL: LEVEL=RL IF USE IMP=YES THEN START RESULT=0 FINISH ELSE START *LSS_0; *J_TOS FINISH BIP(999): ! REPEATED PHRASE A(RR)=ALT; P=PP ->COMM BIP(1000):FINI: ! NULL ALWAYS LAST & OK A(RR)=ALT IF USE IMP=YES THEN START RESULT=1 FINISH ELSE START *LSS_1; *J_TOS FINISH BIP(1001): ! PHRASE NAME BIP(1004): ! PHRASE OLDNAME I=CC(Q); ! OBTAIN CURRENT CHARACTER ->FAIL UNLESS TRTAB(I)=2 PNAME(ITEM-1004) ->SUCC IF HIT=1; ->FAIL BIP(1002): ! PHRASE INTEGER CONSTANT BIP(1003): ! PHRASE CONST CONST(ITEM-1003) ->FAIL IF HIT=0 ->SUCC BIP(1005): ! PHRASE N I=CC(Q); ! OBTAIN CURRENT CHARACTER ->FAIL UNLESS '0'<=I<='9' S=0 WHILE '0'<=I<='9' CYCLE S=10*S+I&15 Q=Q+1; I=CC(Q) REPEAT TOAR2(R,S) R=R+2; ->SUCC BIP(1006): ! PHRASE S=SEPARATOR I=CC(Q); ! OBTAIN CURRENT CHARACTER ->SUCC IF I=NL ->FAIL UNLESS I=';' Q=Q+1; ->SUCC BIP(1007): ! PHRASE COMMENT TEXT I=CC(Q); ! OBTAIN CURRENT CHARACTER J=I ->TX IF I=';' OR I=NL ->FAIL UNLESS I='!' OR I='|' OR (I='C'+128 AND CC(Q+1)=C 'O'+128 AND CC(Q+2)=CC(Q+3)='M'+128 AND CC(Q+4)='E'+128 C AND CC(Q+5)='N'+128 AND CC(Q+6)='T'+128) Q=Q+1+6*(I>>7); J=CC(Q) CYCLE EXIT IF J=NL OR J=';' Q=Q+1; J=CC(Q) REPEAT TX: Q=Q+1 IF J=';' ->SUCC BIP(1008): ! PHRASE BIGHOLE TO AR4(R,0) R=R+4; ->SUCC BIP(1009): ! PHRASE N255 I=CC(Q); ! OBTAIN CURRENT CHARACTER ->FAIL UNLESS '0'<=I<='9' S=0 WHILE '0'<=I<='9' CYCLE S=10*S+I&15 Q=Q+1; I=CC(Q) REPEAT ->FAIL UNLESS 0<=S<=255 A(R)=S; ->UPR BIP(1010): ! PHRASE HOLE MARKER=R; R=R+2; ->SUCC BIP(1011): ! PHRASE MARK I=R-MARKER A(MARKER+1)<-I A(MARKER)<-I>>8 ->SUCC BIP(1012): ! PHRASE READLINE? I=CC(Q); ! OBTAIN CURRENT CHARACTER WHILE I=NL CYCLE READLINE(0,0) RQ=1 I=CC(Q) REPEAT FAULT(102,0) IF R>ARSIZE ->SUCC BIP(1013): ! PHRASE CHECKIMPS ->FAIL UNLESS IMPS=1; ->SUCC BIP(1014): ! PHRASE DUMMY APP A(R)=2; A(R+1)=2 R=R+2; ->SUCC BIP(1015): ! PHRASE DOWN=NEW TEXT LEVEL LEVEL=LEVEL+1 TO AR4(R,0) DISPLAY(LEVEL)=R SFS(LEVEL)=0 R=R+4 ->SUCC BIP(1016): ! PHRASE UP 1 TEXTUAL LEVEL DISPLAY(LEVEL)=0 WHILE SFS(LEVEL)#0 CYCLE POP(SFS(LEVEL),I,J,K) IF I=1 THEN FAULT2(53,K,0); ! FINISH MISSING IF I=2 THEN FAULT2(13,K,0); ! %REPEAT MISSING REPEAT LEVEL=LEVEL-1 ->SUCC BIP(1017): ! PHRASE LISTON LIST=1; ->SUCC BIP(1018): ! PHRASE LISTOFF LIST=0; ->SUCC BIP(1019): ! PHRASE COLON FOR LABEL ->FAIL UNLESS CC(Q-1)=':' ->SUCC BIP(1020): ! PHRASE NOTE CONST IF CTYPE=5 THEN TOAR4(S-4,STRLINK) AND STRLINK=S-4 ->SUCC BIP(1021): ! TRACE FOR ON CONDITIONS PARMTRACE=1; ->SUCC BIP(1022): ! SET MNEMONIC I=CC(Q); ! OBTAIN CURRENT CHARACTER S=M' ' WHILE 'A'<=I<='Z' CYCLE S=S<<8!I; Q=Q+1; I=CC(Q) REPEAT ->FAIL UNLESS I='_' AND S#M' ' Q=Q+1; ->SUCC BIP(1023): ! PRIMARY FORMAT MNEMOINC CYCLE I=7,1,126 ->PFND IF OPC(I)=S REPEAT ->FAIL PFND: ->FAIL IF 8<=I>>3<=11 AND I&7<=3 A(R)=2*I; ->UPR BIP(1024): ! SECONDARY FORMAT MNEMONIC CYCLE I=64,8,88 CYCLE J=0,1,3 ->SFND IF OPC(I+J)=S REPEAT REPEAT ->FAIL SFND: A(R)=2*(I+J); ->UPR BIP(1025): ! TERTIARY FORMAT MNEMONIC CYCLE I=3,-1,1 IF OPC(I)=S THEN A(R)=2*I AND ->UPR REPEAT; ->FAIL BIP(1026): ! P(OP)=+,-,&,****,**,*,!!,!, ! //,/,>>,<<,.,¬¬,¬; I=CC(Q); ! OBTAIN CURRENT CHARACTER ->FAIL UNLESS 32<I<127 AND C X'80000000'>>((I-32)&31)&X'4237000A'#0 Q=Q+1 IF I='+' THEN A(R)=1 AND ->UPR IF I='-' THEN A(R)=2 AND ->UPR IF I='&' THEN A(R)=3 AND ->UPR J=CC(Q) IF I='*' THEN START IF J#I THEN A(R)=6 AND ->UPR IF CC(Q+1)=I=CC(Q+2) THEN A(R)=4 AND Q=Q+3 AND ->UPR A(R)=5; Q=Q+1; ->UPR FINISH IF I='/' THEN START IF J#I THEN A(R)=10 AND ->UPR A(R)=9; Q=Q+1; ->UPR FINISH IF I='!' THEN START IF J#I THEN A(R)=8 AND ->UPR A(R)=7; Q=Q+1; ->UPR FINISH IF I='.' THEN A(R)=13 AND ->UPR IF I=J='<' THEN A(R)=12 AND Q=Q+1 AND ->UPR IF I=J='>' THEN A(R)=11 AND Q=Q+1 AND ->UPR IF I='¬' THEN START IF J#I THEN A(R)=15 AND ->UPR Q=Q+1; A(R)=14; ->UPR FINISH ->FAIL BIP(1027): ! PHRASE CHECK UI I=CC(Q); ! OBTAIN CURRENT CHARACTER ->SUCC IF TRTAB(I)=2 OR I='-' ->SUCC IF X'80000000'>>(I&31)&X'14043000'#0 ->FAIL BIP(1028): ! P(+')=+,-,¬,0 I=CC(Q); ! OBTAIN CURRENT CHARACTER IF I='¬' OR I=X'7E' THEN A(R)=3 AND Q=Q+1 AND ->UPR IF I='-' THEN A(R)=2 AND Q=Q+1 AND ->UPR IF I='+' THEN A(R)=1 AND Q=Q+1 AND ->UPR A(R)=4; ->UPR BIP(1029): ! PHRASE NOTE CYCLE TOAR4(R,0) PUSH(SFS(LEVEL),2,R,LINE) R=R+4 ->SUCC BIP(1030): ! P(,')=',',0 ! ! THIS IS VERY AWKWARD AS IT MEANS IT IS VERY TO HARD TO FIND ! THE END OF A PARAMETER LIST WITHOUT CHURNING. BY MAKING THIS A BIP ! WE CAN PEEP AHEAD FOR ')' AND FAIL HERE. ! I=CC(Q); ! OBTAIN CURRENT CHARACTER IF I=')' THEN ->FAIL IF I=',' THEN Q=Q+1 ->SUCC BIP(1031): ! PHRASE CHECKTYPE IE ENSURE ! FIRST LETTER IS(B,H,I,L,R,S) & ! 3RD LETTER IS (A,L,N,R,T) I=CC(Q); ! OBTAIN CURRENT CHARACTER ->FAIL UNLESS I>128 AND X'80000000'>>(I&31)&X'20C83000'#0C AND X'80000000'>>(CC(Q+2)&31)&X'400A2800'#0 ->SUCC BIP(1032): ! PHRASE COMP1 BIP(1037): ! PHRASE COMP2(IS 2ND HALF OF DSIDED) I=CC(Q); ! OBTAIN CURRENT CHARACTER ->FAIL UNLESS 32<I<=92 AND C X'80000000'>>(I&31)&X'1004000E'#0 ! '='=1,'>='=2,'>'=3 ! '#' OR '¬='=4,'<='=5,'<'=6 ! 7UNUSED,'->'=8,'=='=9 ! '##' OR '¬==' =10 IF I='=' THEN START IF CC(Q+1)=I THEN J=9 AND ->JOIN1 J=1; ->JOIN FINISH IF I='#' THEN START IF CC(Q+1)=I THEN J=10 AND ->JOIN1 J=4; ->JOIN FINISH IF I='¬' AND CC(Q+1)='=' THEN START Q=Q+1 IF CC(Q+1)='=' THEN J=10 AND ->JOIN1 J=4; ->JOIN FINISH IF I='>' THEN START IF CC(Q+1)='=' THEN J=2 AND ->JOIN1 J=3; ->JOIN FINISH IF I='<' THEN START IF CC(Q+1)='=' THEN J=5 AND ->JOIN1 J=6; ->JOIN FINISH IF I='-' AND CC(Q+1)='>' THEN J=8 AND ->JOIN1 ->FAIL JOIN1:Q=Q+1 JOIN: Q=Q+1 A(R)=J IF ITEM=1032 THEN SAVECOMP=J AND ->UPR ! SAVE J TO CHECK DSIDED IF SAVECOMP>6 OR J>6 THEN Q=Q-1 AND ->FAIL; ! ILLEGAL DSIDED ->UPR; ! NB OWNS WONT WORK IF ! COND EXPRS ALLOWED AS THE ! CAN BE NESTED! BIP(1033): ! P(ASSOP)- ==,=,<-,-> I=CC(Q); ! OBTAIN CURRENT CHARACTER IF I='=' THEN START IF CC(Q+1)='=' THEN A(R)=1 AND Q=Q+2 AND ->UPR A(R)=2; Q=Q+1; ->UPR FINISH IF I='<' AND CC(Q+1)='-' THEN A(R)=3 AND Q=Q+2 AND ->UPR IF I='-' AND CC(Q+1)='>' THEN A(R)=4 AND Q=Q+2 AND ->UPR ->FAIL BIP(1034): ! NOTE START TOAR4(R,0); ! HOLE FOR FORWARD PTR PUSH(SFS(LEVEL),1,R,LINE) R=R+4 ->SUCC BIP(1035): ! NOTE FINISH IF SFS(LEVEL)=0 THEN FAULT2(51,0,0) AND ->SUCC POP(SFS(LEVEL),I,J,K) IF I=2 THEN FAULT2(59,K,0) TOAR4(J,STARSTART) ->SUCC BIP(1036): ! NOTE REPEAT IF SFS(LEVEL)=0 THEN FAULT2(1,0,0) AND ->SUCC POP(SFS(LEVEL),I,J,K) IF I=1 THEN FAULT2(52,K,0); ! START INSTEAD OF CYCLE TOAR4(J,STARSTART) ->SUCC BIP(1038): ! INCLUDE "FILE" ->FAIL IF VMEB=YES I=CC(Q) ->FAIL UNLESS I=NL OR I=';' Q=Q+1 IF I=';' ->FAIL UNLESS CTYPE=5 PUSH(IHEAD,FILEADDR,FILEPTR,FILEEND) CONSOURCE(STRING(ADDR(A(S))),FILEADDR);! DEPARTS IF FAILS FILEPTR=FILEADDR+INTEGER(FILEADDR+4) FILEEND=FILEADDR+INTEGER(FILEADDR) ->SUCC 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, T, S, I LONGINTEGER DRDES,ACCDES HIT=0; FQ=Q; FS=CC(Q) RETURN UNLESS TRTAB(FS)=2 AND M'"'#CC(Q+1)#M'''' ! 1ST CHAR MUST BE LETTER T=1 LETT(NEXT+1)=FS; JJ=71*FS IF USE IMP=YES THEN START CYCLE Q=Q+1 I=CC(Q) EXIT IF TRTAB(I)=0 JJ=JJ+HASH(T) IF T<=7 T=T+1 LETT(NEXT+T)=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_T *CPB_7 *JCC_2,<SKIP> *IMY_(HASH+B) *IAD_JJ *ST_JJ SKIP: *ADB_1 *STB_T *LSS_I *ADB_NEXT *ST_(LETT+B) *J_<CYC> EXIT: FINISH LETT(NEXT)=T; ! INSERT LENGTH S=T+1 FAULT(103,0) IF NEXT+S>DSIZE; !DICTIONARY OVERFLOW JJ=(JJ+113*T)&NNAMES IF USE IMP=YES THEN START CYCLE KK=JJ, 1, NNAMES LL=WORD(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=WORD(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_(WORD+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_(WORD+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 Q=FQ AND RETURN WORD(KK)=NEXT; NEXT=NEXT+S FND: LASTAT=FQ; HIT=1; LASTNAME=KK A(R+1)<-LASTNAME A(R)=LASTNAME>>8; R=R+2 LASTEND=Q END ROUTINE CONST(INTEGER MODE) !*********************************************************************** !* SYNTAX CHECK AND EVALUATE ALL THE FORMS OF IMP CONSTANT * !* MODE=0 FOR INTEGER CONSTANTS #0 FOR ANY SORT OF CONSTANT * !*********************************************************************** INTEGER Z, DOTSEEN, EBCDIC, FS, CPREC, RR, S, T, SS LONGLONGREAL X,CVALUE,DUMMY CONSTLONGLONGREAL TEN=R'41A00000000000000000000000000000' CPREC=5; RR=R; R=R+1 DOTSEEN=0; HIT=0 CVALUE=0; DUMMY=0; FS=CC(Q) S=0; ->N IF M'0'<=FS<=M'9' ->DOT IF FS='.' AND MODE=0 AND '0'<=CC(Q+1)<='9' ! 1 DIDT MIN CTYPE=1; EBCDIC=0 ->QUOTE IF FS=M'''' ->STR2 IF FS=34 ->NOTQUOTE UNLESS CC(Q+1)=M''''; Q=Q+2 ->HEX IF FS='X' ->MULT IF FS='M' ->BIN IF FS=M'B' ->RHEX IF FS='R' AND MODE=0 ->OCT IF FS='K' IF FS='C' THEN EBCDIC=1 AND ->MULT IF FS='D' AND MODE=0 THEN START CPREC=7 IF M'0'<=CC(Q)<=M'9' THEN ->N IF CC(Q)='.' THEN ->DOT FINISH Q=Q-2; RETURN QUOTE: ! SINGLE CH BETWEEN QUOTES IF CC(Q+2)=M'''' THEN START S=CC(Q+1) Q=Q+3 IF S#M'''' THEN ->IEND IF CC(Q)=M'''' THEN Q=Q+1 AND ->IEND FINISH RETURN; ! NOT VALID NOTQUOTE: ! CHECK FOR E"...." RETURN UNLESS FS='E' AND CC(Q+1)=M'"' EBCDIC=1; Q=Q+1 STR2: ! DOUBLE QUOTED STRING A(RR)=X'35'; TEXTTEXT(EBCDIC) CTYPE=5; RETURN HEX: T=0; ! HEX CONSTANTS CYCLE I=CC(Q); Q=Q+1 EXIT IF I=M'''' T=T+1 RETURN UNLESS ('0'<=I<='9' OR 'A'<=I<='F') AND T<17 IF T=9 THEN SS=S AND S=0 S=S<<4+I&15+9*I>>6 REPEAT IF T>8 START Z=4*(T-8) S=S!(SS<<Z) SS=SS>>(32-Z); CPREC=6 FINISH IEND: IF CPREC=6 THEN TOAR4(R,SS) AND R=R+4 IF CPREC=5 AND 0<=S<=X'7FFF' START CPREC=4; TOAR2(R,S); R=R+2 FINISH ELSE TOAR4(R,S) AND R=R+4 HIT=1 UNLESS MODE#0 AND CPREC=6 A(RR)=CPREC<<4!CTYPE RETURN RHEX: ! REAL HEX CONSTANTS T=0 CYCLE I=CC(Q); Q=Q+1 IF T&7=0 AND T#0 START TOAR4(R,S); R=R+4; S=0 FINISH EXIT IF I=M''''; T=T+1 RETURN UNLESS '0'<=I<='9' OR 'A'<=I<='F' S=S<<4+I&15+9*I>>6 REPEAT RETURN UNLESS T=8 OR T=16 OR T=32 IF T=32 THEN CPREC=7 ELSE CPREC=4+T//8 A(RR)=CPREC<<4!2 HIT=1; RETURN OCT: ! OCTAL CONSTANTS T=0 CYCLE I=CC(Q); Q=Q+1; T=T+1 EXIT IF I=M'''' RETURN UNLESS '0'<=I<='7' AND T<12 S=S<<3!(I&7) REPEAT ->IEND MULT: T=0; ! MULTIPLE CONSTANTS CYCLE I=CC(Q); Q=Q+1; T=T+1 IF I=M'''' THEN START IF CC(Q)#M'''' THEN EXIT ELSE Q=Q+1 FINISH RETURN IF T>=5 IF EBCDIC#0 THEN I=ITOETAB(I) S=S<<8!I REPEAT ->IEND BIN: T=0; ! BINARY CONST CYCLE I=CC(Q); Q=Q+1; T=T+1 EXIT IF I=M'''' RETURN UNLESS '0'<=I<='1' AND T<33 S=S<<1!I&1 REPEAT ->IEND N: ! CONSTANT STARTS WITH DIGIT I=CC(Q) UNTIL I<M'0' OR I>M'9' CYCLE CVALUE=TEN*CVALUE+(I&15) Q=Q+1; I=CC(Q); ! ONTO NEXT CHAR REPEAT ->ALPHA UNLESS MODE=0 AND I='.' DOT: Q=Q+1; X=TEN; I=CC(Q) DOTSEEN=1; ! CONSTANT HAS DECIMAL POINT WHILE M'0'<=I<=M'9' CYCLE CVALUE=CVALUE+(I&15)/X X=TEN*X; Q=Q+1; I=CC(Q) REPEAT ALPHA: ! TEST FOR EXPONENT IF MODE=0 AND CC(Q)='@' THEN START Q=Q+1; X=CVALUE Z=1; I=CC(Q) IF I='-' THEN Z=-1 IF I='+' OR I='-' THEN Q=Q+1 CONST(2) IF HIT=0 THEN RETURN HIT=0 R=RR+1 IF A(R)>>4#4 THEN RETURN; ! EXPONENT MUST BE HALFINTEGER S=FROM AR2(R+1)*Z IF S=-99 THEN CVALUE=0 ELSE START IF USE IMP=NO THEN START *MPSR_X'8080'; ! MASK OUT REAL OVERFLOW FINISH WHILE S>0 CYCLE S=S-1 CVALUE=CVALUE*TEN IF USE IMP=NO THEN START *JAT_15,<FAIL> FINISH REPEAT WHILE S<0 AND CVALUE#0 CYCLE S=S+1 CVALUE=CVALUE/TEN REPEAT FINISH FINISH ! SEE IF IT IS INTEGER IF FS='D' THEN START I=CC(Q) IF I='''' THEN Q=Q+1 ELSE RETURN DOTSEEN=1; ! ENSURE NOT TAKEN AS INTEGER FINISH IF DOTSEEN=1 OR CVALUE>IMAX OR FRACPT(CVALUE)#0 C THEN CTYPE=2 ELSE CTYPE=1 AND S=INT(CVALUE) IF CTYPE=1 THEN ->IEND IF CPREC=5 THEN CPREC=6; ! NO 32 BIT REAL CONSTS IF CPREC=6 THEN START IF USE IMP=NO THEN START; ! SOFTWARE ROUND IN MC CODE ONLY *LSD_CVALUE *AND_X'FF00000000000000' *SLSD_CVALUE+8 *AND_X'0080000000000000' *LUH_TOS *RAD_CVALUE *ST_CVALUE FINISH FINISH TOAR8(R,CVALUE); R=R+8 IF CPREC=7 THEN TOAR8(R,LONGREAL(ADDR(CVALUE)+8)) C AND R=R+8 A(RR)=CPREC<<4+CTYPE HIT=1 FAIL: END ROUTINE TEXTTEXT(INTEGER EBCDIC) !*********************************************************************** !* PROCESSES TEXT BETWEEN DOUBLE QUOTES AND STORES IN ISO OR EBCDIC * !*********************************************************************** INTEGER J, II CONSTINTEGER QU='"' I=CC(Q) S=R+4; R=R+5; HIT=0 RETURN UNLESS I=QU; ! FAIL UNLESS INITIAL QUOTE Q=Q+1 CYCLE I=CC(Q) IF EBCDIC#0 THEN II=ITOETAB(I) ELSE II=I A(R)=II; R=R+1 IF I=QU THEN START Q=Q+1 IF CC(Q)#QU THEN EXIT FINISH IF I=10 THEN READLINE(1,QU) ELSE Q=Q+1 FAULT(106,0) IF R-S>256 REPEAT R=R-1; J=R-S-1 A(S)=J; HIT=1 END BEND:END; ! OF BLOCK CONTAINING PASS 1 IF LEVEL>1 THEN FAULT(15, 0) I=0 NEWLINE IF FAULTY=0 THEN START WRITE(LINE, 5) PRINT STRING(" LINES ANALYSED IN") WRITE(INT(1000*(CPUTIME-CTIME)),5) PRINT STRING(" MSECS - SIZE=") WRITE(P1SIZE, 5) IF LINE>90 AND LIST#0 THEN NEWPAGE ELSE NEWLINE FINISH ELSE START PRINTSTRING("CODE GENERATION NOT ATTEMPTED ") COMREG(24)=8 COMREG(47)=FAULTY STOP FINISH BEGIN !*********************************************************************** !* SECOND OR CODE GENERATING PASS * !*********************************************************************** INTEGERARRAY REGISTER, GRUSE, GRAT, GRINF1, GRINF2, OLINK(0:7) BYTEINTEGERARRAY CODE, GLABUF(0:268) INTEGERARRAY PLABS, DESADS, PLINK(0:31) INTEGERARRAY SET, STACKBASE, RAL, FLAG, L, M, NMDECS, ONWORD, ONINF,C JUMP, LABEL, JROUND, DIAGINF, DISPLAY, C AUXSBASE, NAMES (0:MAXLEVELS) INTEGERARRAY AVL WSP(0:4,0:MAXLEVELS) INTEGERARRAYFORMAT CF(0:12*NNAMES) INTEGERARRAYNAME CTABLE 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 NOTE CREF(INTEGER CA,VAL) INTEGERFNSPEC PARAM DES(INTEGER PREC) INTEGERFNSPEC MAPDES(INTEGER PREC) INTEGERFNSPEC SPECIAL CONSTS(INTEGER WHICH) ROUTINESPEC STORE CONST(INTEGERNAME D,INTEGER L,AD) ROUTINESPEC DUMP CONSTS ROUTINESPEC PLANT(INTEGER VALUE) ROUTINESPEC PLUG(INTEGER I, J, K, BYTES) ROUTINESPEC CODEOUT ROUTINESPEC PROLOGUE ROUTINESPEC EPILOGUE ROUTINESPEC COMPILE A STMNT ROUTINESPEC CSS(INTEGER P) ROUTINESPEC LOAD DATA ROUTINESPEC ABORT !*DELSTART ROUTINESPEC PRINT USE !*DELEND CYCLE I=0,1,7 REGISTER(I)=0; GRUSE(I)=0; GRINF1(I)=0; GRAT(I)=0 GRINF2(I)=0 REPEAT CYCLE I=0, 1, MAXLEVELS SET(I)=0; STACKBASE(I)=0; RAL(I)=0 JUMP(I)=0; JROUND(I)=0 LABEL(I)=0; FLAG(I)=0 L(I)=0; M(I)=0; DIAGINF(I)=0 DISPLAY(I)=0; ONWORD(I)=0; ONINF(I)=0 NAMES(I)=-1 CYCLE J=0,1,4 AVL WSP(J,I)=0 REPEAT REPEAT CTABLE==ARRAY(ADDR(ASLIST(1)),CF) CONST HOLE=0 PROLOGUE LINE=0 NEXTP=1; LEVEL=1; STMTS=0 RLEVEL=0; RBASE=0 WHILE A(NEXTP+3)!A(NEXTP+4)#0 CYCLE COMPILE A STMNT REPEAT LINE=99999 EPILOGUE LOAD DATA STOP ROUTINE COMPILE A STMNT INTEGER I !*DELSTART IF DCOMP#0 AND CA>CABUF THEN CODEOUT AND PRINTUSE !*DELEND I=NEXTP NEXTP=NEXTP+A(NEXTP)<<16+A(NEXTP+1)<<8+A(NEXTP+2) LINE=A(I+3)<<8+A(I+4) STMTS=STMTS+1 CSS(I+5) ! CHECK ASL %IF LINE&7=0 END ROUTINE LOAD DATA !*********************************************************************** !* PASS INFORMATION TO LPUT TO ENABLE IT TO GENERATE THE * !* LOADER DATA AND COMPLETE THE PROGRAM FILE. * !*********************************************************************** INTEGER LANGFLAG,PARMS GLACA=(GLACA+7)&(-8) USTPTR=(USTPTR+7)&(-8) CODE OUT CNOP(0, 8) DUMP CONSTS IF PARMTRACE=0 THEN LANGFLAG=6 ELSE LANGFLAG=1 LANGFLAG=LANGFLAG<<24 PARMS=(PARMDIAG<<1!PARMLINE)<<1!PARMTRACE FIXED GLA(4)=LANGFLAG!1<<16!(CPRMODE&1)<<8!PARMS;! LANG RLSE & MAINPROG I=GLACA-GLACABUF IF INHCODE=0 THEN START LPUT(2, I, GLACABUF, ADDR(GLABUF(0))) UNLESS I=0 ! BACK OF GLAP LPUT(2, FIXEDGLALEN, 0, ADDR(FIXED GLA(0)));! FRONT OF GLAP LPUT(19,2,8,5); ! RELOCATE GLA ST ADDRESS LPUT(19,2,12,4); ! RELOCATE CODE ST ADDRESS I=X'E2E2E2E2' LPUT(4, 4, SSTL, ADDR(I)) ! FINISH SSTL=(SSTL+11)&(-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; PRINT CH(13); ! MARKER FOR COMP TO PRINT !SUMMARY IF FAULTY=0 THEN START WRITE(STMTS, 7); PRINTSTRING(" STATEMENTS COMPILED IN") WRITE(INT(1000*(CPUTIME-CTIME)),5) PRINTSTRING(" MSECS") COMREG(47)=STMTS; ! NO OF STMTS FOR COMPER FINISH ELSE START PRINTSTRING("PROGRAM CONTAINS"); WRITE(FAULTY, 2) PRINTSTRING(" FAULT"); PRINTSYMBOL('S') IF FAULTY>1 COMREG(47)=FAULTY; ! NO OF FAULTS FOR COMPER FINISH NEWLINES(2) NEWLINE 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 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 * !*********************************************************************** !*DELSTART ROUTINE RECODE(INTEGER S,F,AD) IF S#F START PRINTSTRING(" CODE FOR LINE"); WRITE(LINE,5) NCODE(S,F,AD) FINISH END !*DELEND ROUTINE CODEOUT IF PPCURR>0 THEN START !*DELSTART RECODE(ADDR(CODE(0)), ADDR(CODE(PPCURR)), CABUF) C IF DCOMP#0 !*DELEND 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 USE IMP=YES 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 USE IMP=YES 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 USE IMP=YES 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=(N-CA)//2 FINISH IF (1<<KPP)&B'101100'#0 THEN N=N//4 IF USE IMP=YES 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) ORC (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 USE IMP=YES 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=(N-CA)//2 FINISH IF (1<<KPP)&B'101100'#0 THEN N=N//4 IF USE IMP=YES 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=(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,N) !*********************************************************************** !* 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 !%CONSTINTEGERARRAY FIXED CODE(0:127) ! %CYCLE I=FROM, 1, TO ! PCONST(FIXED CODE(I)) ! %REPEAT END ROUTINE CNOP(INTEGER I, J) PSF1(JUNC,0,1) WHILE CA&(J-1)#I 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 CYCLE I=0,1,L-1 GLABUF(GLACURR+I)=BYTE INTEGER(I+INF ADR) REPEAT GLACA=GLACA+L; GLACURR=GLACURR+L END ROUTINE PLUG(INTEGER AREA, AT, VALUE, BYTES) !*********************************************************************** !* WRITE UP TO ONE WORD INTO OBJECT FILE OUT OF SEQUENCE * !*********************************************************************** INTEGERNAME WCABUF INTEGER I, RELAD, BUFAD WCABUF==CABUF; BUFAD=ADDR(CODE(0)) IF AREA=2 THEN WCABUF==GLACABUF AND BUFAD=ADDR(GLABUF(0)) RELAD=AT-WCABUF IF 0<=RELAD<=256 AND AREA<=3 THEN START CYCLE I=0,1,BYTES-1 BYTEINTEGER(RELAD+BUFAD+I)<-VALUE>>((BYTES-1-I)<<3) REPEAT FINISH ELSE START IF RELAD=-2 THEN CODEOUT IF INHCODE=0 THEN LPUT(AREA,BYTES,AT,ADDR(VALUE)+4-BYTES) !*DELSTART NCODE(ADDR(VALUE)+4-BYTES,ADDR(VALUE)+4,AT) IF DCOMP=1=AREA !*DELEND FINISH END INTEGERFN PARAM DES(INTEGER PREC) !*********************************************************************** !* SET UP BNDED L=1 DESRIPTOR FOR PASSING VARIABLE BY REFERENCE * !* ONLY THE TOP HALF IS SET UP * !*********************************************************************** INTEGER K,DES K=DESADS(PREC) RESULT=K UNLESS K=0 IF PREC=4 THEN DES=X'58000002' ELSE DES=PREC<<27!1 STORE CONST (K,4,ADDR(DES)) DESADS(PREC)=K RESULT=K END INTEGERFN MAPDES(INTEGER PREC) !*********************************************************************** !* SET UP 8BIT ZERO ADDRESS UNSCALED BCI DESCRTR FOR MAPPING * !*********************************************************************** INTEGER K,DES0,DES1 K=DESADS(PREC+8) RESULT=K UNLESS K=0 IF PREC=4 THEN DES0=X'58000002' ELSE DES0=X'03000000'!PREC<<27 DES1=0; STORE CONST(K,8,ADDR(DES0)) DESADS(PREC+8)=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, 1,0; INTEGER K K=DESADS(WHICH+16) RESULT=K UNLESS K=0 STORE CONST(K,8,ADDR(SCS(2*WHICH))) DESADS(WHICH+16)=K RESULT=K END ROUTINE STORE CONST(INTEGERNAME D, INTEGER L, AD) !*********************************************************************** !* 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, C1, C2, C3, C4, LP LP=L//4; C2=0; C3=0; C4=0 CYCLE I=0,1,L-1 BYTEINTEGER(ADDR(C1)+I)=BYTEINTEGER(AD+I) REPEAT IF PARMOPT#0 THEN ->SKIP K=CONST BTM; ! AFTER STRINGS IN CTABLE IF L=4 THEN START IF USE IMP=YES 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 WHILE K<=J CYCLE IF CTABLE(K)=C1 AND CTABLE(K+1)=C2 AND C (CONSTHOLE<K OR CONSTHOLE>=K+LP) START IF L=8 OR (CTABLE(K+2)=C3 C AND CTABLE(K+3)=C4) THEN D=4*K!X'80000000' C AND RETURN FINISH K=K+2 REPEAT 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 IF L=16 THEN CTABLE(CONSTPTR+2)=C3 C AND CTABLE(CONSTPTR+3)=C4 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, USE CYCLE I=0, 1, 7 USE=GRUSE(I)&X'FF'; ! MAIN USE ONLY PUSH(HEAD, GRINF1(I), GRAT(I), I<<8!USE) IF USE#0 REPEAT END ROUTINE RESTORE(INTEGER HEAD) !*********************************************************************** !* RESET THE REGISTERS TO ENVIRONMENT IN LIST HEADED BY 'HEAD' * !*********************************************************************** INTEGER I, R, USE, INF, AT CYCLE I=0, 1, 7 IF REGISTER(I)>=0 THEN GRUSE(I)=0 AND GRINF1(I)=0 REPEAT WHILE HEAD#0 CYCLE POP(HEAD, INF, AT, I) R=I>>8; USE=I&255 IF REGISTER(R)>=0 THEN GRUSE(R)=USE AND GRINF1(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(8,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(8,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,4) 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, K, L, STCA I=X'C2C2C2C2' LPUT(4,4,0,ADDR(I)) SSTL=4 CYCLE I=0, 1, 31 PLABS(I)=0; PLINK(I)=0 DESADS(I)=0 REPEAT ! ! 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 & XTRA ARE IN ACC AS 64 BIT INTEGER ! ENTRY HAS BEEN BY JLK SO RETURN ADDRESS STACKED ! !RTF PRCL 4 TO PLANT PARAMS ! JLK +1 STACK DUMMY PC ! STLN TOS LNB AS SECOND PARAMETER ! ST TOS ERROR NO AS THIRD PARAM ! 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 PSF1(PRCL,0,4) PSF1(JLK,0,1) PF1(STLN,0,TOS,0) PF1(ST,0,TOS,0) PSF1(LXN,1,16) PSF1(RALN,0,9) PF1(CALL,2,XNB,40) PF1(JUNC,0,TOS,0) ! ! SUBROUTINE TO CALL DEBUG ROUTINE(S#IMPMON) LINE NO IN ACC ! ! PRCL 4 ! ST TOS ! LXN (LNB+4) ! RALN 6 ! CALL ((XNB+IMPMONEPDISP)) ! JUNC TOS ! IF PARMDBUG#0 THEN START PLABS(3)=CA CXREF("S#IMPMON",PARMDYNAMIC,2,K) PSF1(PRCL,0,4) PF1(ST,0,TOS,0) PSF1(LXN,1,16) PSF1(RALN,0,6) PF1(CALL,2,XNB,K) PF1(JUNC,0,TOS,0) FINISH ! ! 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); K=CA PCONST(X'58000000') PLABS(4)=CA PF3(JAT,12,0,13) PF1(LSS,0,TOS,0) PF1(STSF,0,TOS,0) PF1(LDTB,0,PC,K) 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) FINISH ! ! SOME ERROR ROUTINES ! ERR EXIT(5, X'801', 0) IF PARMOPT#0; ! UNASSIGNED VARIABLE ERR EXIT(6, X'504', 0); ! SWITCH LABEL UNSET ERR EXIT(7, X'505', 1); ! ILLEGEAL EXPONENTIATION ERR EXIT(8,X'201', 0) IF PARMOPT#0; ! EXCESS BLOCKS ERR EXIT(9, X'601', 0); ! CAPACITY EXCEEDED ERR EXIT(10,21, 0) ; ! NO RESULT ERR EXIT(11,X'501', 0) IF PARMOPT#0; ! CYCLE NOT VALID ERR EXIT(12,X'701',0); ! RES FAILS ERR EXIT(13,36,0) IF PARMOPT#0; ! WRONG NO OF PARAMS ! ! PUT THE STRINGS ONTO THE FRONT OF CONSTANT AREA ! CTABLE(0)=X'18000001' CTABLE(1)=4 STCA=8; L=ADDR(CTABLE(0)) CONST PTR=2; ! IN CASE NO STRINGS WHILE STRLINK#0 CYCLE I=STRLINK; STRLINK=FROM AR4(I) TO AR4(I,STRINGIN(I+4)); ! CHANGE LINK TO STRING ADDR REPEAT STRLINK=X'80000000' CONST BTM=CONST PTR IF PARMOPT#0 THEN CTABLE(CONST PTR)=M'IDIA' AND C CONST PTR=CONST PTR+1 GXREF(MDEP,PARMDYNAMIC,2,40) IF PARMPROF#0 THEN START; ! ALLOCATE PROFILE COUNT AREA I=X'38000001'+LINE K=8 PARMPROF=GLACA PGLA(4,8,ADDR(I)) K=0 CYCLE I=0,1,LINE PGLA(4,4,ADDR(K)) REPEAT LINE=0 FINISH LEVEL=1 CYCLE I=0,1,31 IF PLINK(I)#0 THEN CLEAR LIST(PLINK(I)) REPEAT RETURN INTEGERFN STRINGIN(INTEGER POS) !*********************************************************************** !* PUT A STRING INTO THE CONSTANT AREA CHECKING FOR DUPLICATES * !*********************************************************************** INTEGER J,K,IND,HD RECORDNAME CELL(LISTF) K=A(POS) IF K=0 THEN RESULT=0 IND=K&31; HD=PLINK(IND) WHILE HD#0 CYCLE 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 BYTEINTEGER(L+STCA)=K; STCA=STCA+1 CYCLE J=POS+1,1,POS+K BYTE INTEGER(L+STCA)=A(J) 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 BREG * !*********************************************************************** PLABS(LAB)=CA IF MODE=0 THEN PSF1(LSS,0,0) ELSE PF1(LSS,0,BREG,0) PSF1(LUH,0,ERRNO) PSF1(JLK,0,(PLABS(2)-CA)//2) END END ROUTINE CSS(INTEGER P) ROUTINESPEC MERGE INFO ROUTINESPEC REDUCE ENV(INTEGERNAME HEAD) ROUTINESPEC ENTER JUMP(INTEGER MASK,STAD,FLAG) INTEGERFNSPEC ENTER LAB(INTEGER M,FLAG) ROUTINESPEC REMOVE LAB(INTEGER LAB) ROUTINESPEC CEND(INTEGER KKK) INTEGERFNSPEC CCOND(INTEGER CTO,A,B) ROUTINESPEC CHECK STOF INTEGERFNSPEC REVERSE(INTEGER MASK) ROUTINESPEC SET LINE INTEGERFNSPEC SET XORYNB(INTEGER WHICH,RLEVEL) INTEGERFNSPEC XORYNB(INTEGER USE,INF) ROUTINESPEC GET IN ACC(INTEGER ACC,SIZE,AC,AREA,DISP) INTEGERFNSPEC AREA CODE INTEGERFNSPEC AREA CODE2(INTEGER BS) ROUTINESPEC CUI(INTEGER CODE) ROUTINESPEC ASSIGN(INTEGER A,B) ROUTINESPEC CSTART(INTEGER CCRES,MODE) ROUTINESPEC CCYCBODY(INTEGER UA,ELAB,CLAB) ROUTINESPEC CLOOP(INTEGER ALT,MARKC,MARKUI) ROUTINESPEC CIFTHEN(INTEGER MARKIU,MARKC,MARKUI,MARKE,MARKR,SKIP) ROUTINESPEC CREATE AH(INTEGER MODE) ROUTINESPEC TORP(INTEGERNAME HEAD,BOT,NOPS) INTEGERFNSPEC INTEXP(INTEGERNAME VALUE) INTEGERFNSPEC CONSTEXP(INTEGER PRECTYPE) ROUTINESPEC CSEXP(INTEGER REG,MODE) ROUTINESPEC CSTREXP(INTEGER A,B) ROUTINESPEC CRES(INTEGER LAB) ROUTINESPEC EXPOP(INTEGER A,B,C,D) ROUTINESPEC TEST APP(INTEGERNAME NUM) ROUTINESPEC SKIP EXP ROUTINESPEC SKIP APP ROUTINESPEC NO APP INTEGERFNSPEC DOPE VECTOR(INTEGER A,B,MODE,ID,INTEGERNAME C,D) ROUTINESPEC DECLARE ARRAYS(INTEGER A,B) ROUTINESPEC DECLARE SCALARS(INTEGER A,B) ROUTINESPEC MAKE DECS(INTEGER Q) ROUTINESPEC SAVE AUX STACK ROUTINESPEC RESET AUX STACK ROUTINESPEC CRSPEC(INTEGER M) ROUTINESPEC CFPLIST(INTEGERNAME A,B) ROUTINESPEC CFPDEL ROUTINESPEC CLT ROUTINESPEC CQN(INTEGER P) ROUTINESPEC GET WSP(INTEGERNAME PLACE,INTEGER SIZE) ROUTINESPEC RETURN WSP(INTEGER PLACE,SIZE) INTEGERFNSPEC TSEXP(INTEGERNAME VALUE) ROUTINESPEC CRCALL(INTEGER RTNAME) ROUTINESPEC NAMEOP(INTEGER Z,REG,SIZE,NAMEP) ROUTINESPEC CNAME(INTEGER Z,REG) ROUTINESPEC CANAME(INTEGER Z,BS,DP) ROUTINESPEC CSNAME(INTEGER Z,REG) ROUTINESPEC TEST ASS(INTEGER REG,TYPE,SIZE) ROUTINESPEC COPY TAG(INTEGER KK) ROUTINESPEC REDUCE TAG ROUTINESPEC REPLACE TAG (INTEGER KK) ROUTINESPEC RT JUMP(INTEGER CODE,INTEGERNAME L) ROUTINESPEC STORE TAG(INTEGER KK,SLINK) ROUTINESPEC UNPACK ROUTINESPEC PACK(INTEGERNAME PTYPE) ROUTINESPEC DIAG POINTER(INTEGER LEVEL) ROUTINESPEC RDISPLAY(INTEGER KK) ROUTINESPEC RHEAD(INTEGER KK) ROUTINESPEC ODD ALIGN INTEGERFNSPEC PTR OFFSET(INTEGER RLEV) ROUTINESPEC PPJ(INTEGER MASK,N) ROUTINESPEC CRFORMAT(INTEGERNAME OPHEAD) INTEGERFNSPEC DISPLACEMENT(INTEGER LINK) INTEGERFNSPEC COPY RECORD TAG(INTEGERNAME SUBS) ROUTINESPEC SAVE IRS ROUTINESPEC COPY DR ROUTINESPEC BOOT OUT(INTEGER REG) ROUTINESPEC CHANGE RD(INTEGER REG) ROUTINESPEC FORGET(INTEGER REG) ROUTINESPEC REMEMBER ROUTINESPEC NOTE ASSMENT(INTEGER REG,ASSOP,VAR) SWITCH SW(1:24) RECORDFORMAT RD(BYTEINTEGER UPTYPE,PTYPE,XB,FLAG,C INTEGER D,XTRA) INTEGER SNDISP,ACC,K,KFORM,STNAME,MIDCELL INTEGER TCELL,NUMMOD,JJ,JJJ,KK,QQ,MARKER,REPORTUI,XDISP,MASK, C BASE,AREA,ACCESS,DISP,EXTRN, CURR INST,VALUE,STRINGL, C PTYPE,I,J,OLDI,USEBITS,TWSPHEAD,KKK,STRFNRES, C MARKIU,MARKUI,MARKC,MARKE,MARKR INTEGER LITL,ROUT,NAM,ARR,PREC,TYPE RECORD EXPOPND(RD); ! RESULT RECORD FOR EXPOP CURR INST=0 TWSPHEAD=0 INTEGERARRAY SGRUSE,SGRINF(0:7) ->SW(A(P)) SW(23): ! INCLUDE SOMETHING SW(24): ! REDUNDANT SEP SW(2): ! <CMARK> <COMMENT TEXT> CSSEXIT: LAST INST=CURR INST WHILE TWSPHEAD#0 CYCLE POP(TWSPHEAD,JJ,KK,QQ) RETURN WSP(JJ,KK) REPEAT RETURN SW(1): !(UI)(S) FAULT(57,0) UNLESS LEVEL>=2 MARKER=P+1+A(P+1)<<8+A(P+2) P=P+3 ->LABFND IF A(MARKER)=1 IF A(MARKER)=2 THEN SET LINE AND CUI(0) AND ->CSSEXIT MARKE=0; MARKR=0 MARKUI=P; MARKIU=MARKER+1 MARKC=MARKIU+1 IF A(MARKER)=3 THEN CIFTHEN(MARKIU,MARKC,MARKUI,0,0,NO) C AND ->CSSEXIT CLOOP(A(MARKIU),MARKC+2,MARKUI) ->CSSEXIT LABFND: ->SWITCH UNLESS A(P)=1 AND A(P+5)=2; ! 1ST OF UI AND NO APP ->SWITCH UNLESS A(P+6)=2 AND A(P+7)=2; ! NO ENAMSE OR ASSNMNT JJ=ENTER LAB(FROM AR2(P+3),0); ->CSSEXIT SW(5): ! %CYCLE FAULT(57,0) UNLESS LEVEL>=2 IF A(P+5)=2 THEN START; ! OPEN CYCLE CLOOP(0,P+1,0) FINISH ELSE START CLOOP(6,P+6,P+1) FINISH ->CSSEXIT ! SW(6): ! REPEAT ->CSSEXIT SW(22): ! '%CONTROL' (CONST) J=FROM AR4(P+2) CODEOUT DCOMP=J>>28; ->CSSEXIT ! SW(3): ! (%IU)(COND)%THEN(UI)(ELSE') MARKIU=P+1; MARKC=MARKIU+3 MARKR=P+2+A(P+2)<<8+A(P+3); ! ! FROMAR2(P+2) MARKE=0 IF A(MARKR)=3 THEN START MARKE=MARKR+1+FROMAR2(MARKR+1) MARKUI=MARKR+3 FINISH CIFTHEN(MARKIU,MARKC,MARKUI,MARKE,MARKR,NO) ->CSSEXIT SW(4): ! '%FINISH(ELSE')(S) ->CSSEXIT SWITCH: BEGIN; ! SWITCH LABEL INTEGER HEAD,BASEPT,NAPS,FNAME INTEGERARRAY BITS(0:2) FORGET(-1) FNAME=FROM AR2(P+3) UNLESS A(P)=1 AND A(P+5)=1 THEN FAULT2(5,0,FNAME) AND ->BEND ! 1ST OF UI + APP P=P+3; TEST APP(NAPS) P=P+6 UNLESS INTEXP(JJ)=0 THEN FAULT2(41,0,0) AND ->BEND ! UNLESS EXPRESSION EVALUATES AND UNLESS NAPS=1 THEN FAULT2(21,NAPS-1,FNAME) AND ->BEND ! NO REST OF APP UNLESS A(P+1)=2=A(P+2) THEN FAULT2(5,0,FNAME) AND ->BEND ! NO ENAME OR REST OF ASSIGMENT COPY TAG(FNAME) HEAD=K IF OLDI#LEVEL OR TYPE#6 THEN FAULT(4,FNAME) AND ->BEND FROM123(HEAD,BASEPT,KKK,KK); ! EXTRACT TABLE ADDR,LB & UB MLINK(HEAD); ! K POINTS TO BIT LIST ->INBD IF KKK<=JJ<=KK FAULT2(50,JJ,FNAME); ->BEND INBD: Q=JJ-KKK WHILE Q>=96 CYCLE MLINK(HEAD) Q=Q-96 REPEAT ! ! ASLIST(HEAD) IS THE START OF 96 BIT ENTRY IN THE BIT LIST ! CHECK BIT NO Q TO SEE IF LABEL ALREADY SET AND THEN SET BIT Q ! FROM123(HEAD,BITS(0),BITS(1),BITS(2)) QQ=Q>>5; ! RIGHT WORD Q=Q&31; JJJ=1<<Q; ! BIT IN WORD FAULT2(6,JJ,FNAME) UNLESS BITS(QQ)&JJJ=0 BITS(QQ)=BITS(QQ)!JJJ REPLACE123(HEAD,BITS(0),BITS(1),BITS(2)) ! ! OPTIMISED (ARR=2) SWITCHES BASEPT POINTS TO THE ! ZEROETH NOT THE FIRST ELEMENT ! IF ARR=2 THEN KKK=0; ! RESET LB IF DESC TO ELEMNT 0 QQ=BASEPT+(JJ-KKK)*4; ! REL POSITION OF LABEL PLUG(2,QQ,CA,4); ! OVERWRITE THE WORD IN TABLE ! RELOCATION(BY HD OF CODE) INTACT BEND: END; ->CSSEXIT SW(7): ! (%WU)(SC)(COND)(RESTOFWU) FAULT(57,0) UNLESS LEVEL>=2 MARKIU=P+1; ! TO WHILE/UNTIL MARKC=MARKIU+3; ! TO (SC)(COND) CLOOP(A(MARKIU)+3,MARKC,MARKIU+1+FROMAR2(MARKIU+1)) ->CSSEXIT ! SW(8): ! SIMPLE DECLN FAULT(57,0) UNLESS LEVEL>=2 FAULT(40,0) IF NMDECS(LEVEL)&1#0 QQ=P; P=P+5;CLT;ROUT=0; LITL=0 IF A(P)#1 THEN START; ! ARRAY DECLARATIONS FAULT(70,0) IF TYPE=5 AND ACC=0 NAM=0 SET LINE QQ=2-A(P+1); P=P+2; ! QQ=1 FOR ARRAYFORMATS DECLARE ARRAYS(QQ,0) FINISH ELSE START IF A(QQ+1)=128 THEN START; ! NOT LINKED&SHUFFLED CQN(P+1); P=P+2 DECLARE SCALARS(1,0) FINISH FINISH ->CSSEXIT ! SW(9): ! %END BEGIN SWITCH S(1:5) -> S(A(P+1)) S(1): ! ENDOFPROGRAM S(2): ! ENDOFFILE IF CPRMODE=0 THEN CPRMODE=2 FAULT(15,0) UNLESS LEVEL+CPRMODE=3 FAULT(56,0) UNLESS A(P+1)=CPRMODE CEND(CPRMODE) ->BEND S(3): ! ENDOFLIST LIST=0; ->BEND S(4): ! END CEND(FLAG(LEVEL)) BEND: END ->CSSEXIT ! SW(11): BEGIN INTEGER MARKER1,KK,KKK STRING(34)XNAME P=P+1; MARKER1=FROM AR2(P)+P; ! (SEX)(RT)(SPEC')(NAME)(FPP) AGN: Q=P; KK=FROM AR2(MARKER1+5); ! KK ON NAME EXTRN=A(P+2) LITL=EXTRN&3 IF A(MARKER1)=1 THEN START; ! P<%SPEC'>='%SPEC' P=P+3; CRSPEC(1-EXTRN>>2);! 0 FOR ROUTINESPEC ! 1 FOR EXTERNAL (ETC) SPEC ->BEND FINISH COPY TAG(KK) IF OLDI=LEVEL THEN START IF CPRMODE=0 THEN CPRMODE=2; ! FLAG AS FILE OF ROUTINES ! IF (CPRMODE=2 AND LEVEL=1) START IF EXTRN=3 THEN EXTRN=2 XNAME<-STRING(DICTBASE+WORD(KK)) IF EXTRN=1 THEN XNAME<-"S#".XNAME IF EXTRN=4 THEN XNAME="" JJ=MIDCELL; ! CODE DESCRIPTOR REL ADDR IF EXTRN#4 THEN USEBITS=2 DEFINE EP(XNAME,CA,JJ,0) IF JJ#0 THEN PSF1(INCA,0,-JJ) FINISH ELSE START; ! EXTERNALS IN PRGM OR WRNG LEVEL FAULT(55,KK) UNLESS EXTRN=4; EXTRN=4 FINISH IF A(P+3)=1 THEN KKK=LITL<<14!X'1000' ELSE START ROUT=1; P=P+4; ! FIGURE OUT PTYPE FOR FNS&MAPS CLT; ARR=0; NAM=0 IF A(P)=2 THEN NAM=2; ! SET NAME ARRAY BIT FOR MAPS PACK(KKK); ! AND STORE PTYPE IN KKK FINISH FINISH UNLESS OLDI=LEVEL AND J=15 AND PTYPE=KKK START P=Q+3; CRSPEC(0); P=Q; ->AGN FINISH PTYPE=PTYPE!(EXTRN&3)<<14; ! DEAL WITH %ROUTINESPEC FOLLOWED ! BY %EXTERNALROUTINE BEGIN INTEGER PTR,PTYPEP,CNT,PP J=0; REPLACE TAG(KK);! BODY GIVEN SO UPDATE TAGS INFO JJ=K; PLABEL=PLABEL-1 UNLESS COMPILER=1 OR (CPRMODE=2 AND LEVEL=1) START IF JROUND(LEVEL+1)=0 START; ! NOT JUMP OUTSTANDING JROUND(LEVEL+1)=PLABEL ENTER JUMP(15,PLABEL,0) FINISH FINISH PTYPEP=PTYPE P=MARKER1+7 RHEAD(KK) N=20; CNT=1 WHILE A(P)=1 CYCLE; ! WHILE SOME (MORE) FP PART PP=P+1+FROMAR2(P+1) P=P+3 CFPDEL PTR=P UNTIL A(PTR-1)=2 CYCLE; ! CYCLE DOWN NAMELIST IF JJ#0 THEN START FROM12(JJ,J,JJJ); ! EXTRACT PTYPE XTRA INFO UNLESS J>>16=PTYPE AND(PTYPE#5 OR JJJ>>16=ACC)C THEN FAULT2(9,CNT,KK) FINISH ELSE FAULT2(8,0,KK); ! MORE FPS THAN IN SPEC PTR=PTR+3 CNT=CNT+1 MLINK(JJ) REPEAT DECLARE SCALARS(0,0) P=PP REPEAT; ! UNTIL NO MORE FP-PART N=(N+3)&(-4); ! TO WORD BOUNDARY AFTER ALL SYSTEM ! STANDARD PARAMETERS HAVE BEEN DECLARED FAULT2(10,0,KK) UNLESS JJ=0 PTYPE=PTYPEP IF PTYPE&X'F0F'=5 THEN N=N+8; ! STR FNS RESULT PARAM IS STACKED ! AS XTRA PARM JUST BEFORE DISPLAY RDISPLAY(KK) MAKE DECS(MARKER1+1) END BEND: END; ->CSSEXIT ! SW(13): !REALS(LN) FAULT(58,0) UNLESS CPRMODE=0 ALL LONG=A(P+1)&1;->CSSEXIT ! SW(14): !%BEGIN BEGIN PTYPE=0 IF LEVEL=1 AND RLEVEL=0 AND CPRMODE=0 START CODE DES(JJ) DEFINE EP(MAINEP, CA, JJ, 1) RLEVEL=1; RBASE=1 L(1)=0; M(1)=0; DIAGINF(1)=0; AUXSBASE(1)=0 CPRMODE=1 N=24; NMAX=N FORGET(-1) DIAG POINTER(LEVEL+1) ! ! THE CODE PLANTED IS AS FOLLOWS:- ! STD (LNB+3) SAVE DESCRIPTOG TO GLA(PLT) ! LXN (LNB+4) TO GLA(PLT) ! STLN (XNB+5) SAVE LNB FOR STOP SEQUENCE ! ASF 1 FOR REPORT WORD ! PSF1(STD,1,12) PSF1(LXN,1,16) PF1(STLN,0,XNB,20) ! PSF1(ASF,0,1) ! ! THE NEXT 8 INSTRUCTIONS ARE REQUIRED TO SET SF 6 WORDS IN FRONT OF LNB ! AN ASF 1 WORKS AS WELL EXCEPT FOR K-STAND ALONE WHEN THERE MAY BE ! A USELESS REDUNDANT DESCRIPTOR ON THE STACK ! PF1(STLN,0,TOS,0) PF1(LSS,0,TOS,0) PSF1(IAD,0,24) PF1(STSF,0,TOS,0) PF1(ISB,0,TOS,0) PSF1(ISH,0,-2) PF1(ST,0,BREG,0) PF1(ASF,0,BREG,0) ! ! ! SET THE PROGRAM MASK TO MASK OUT UNDERFLOW AND ALLOW ALL OTHER INTS ! ! MPSR X'40C0' ! PF1(MPSR,0,0,X'40C0') PTYPE=1 FINISH ELSE SET LINE; ! SO 'ENTERED FROM LINE' IS OK RHEAD(-1) RDISPLAY(-1) MAKE DECS(P+1) END ->CSSEXIT ! SW(15): ! '%ON'(EVENT')(N)(NLIST)'%START' FAULT(57,0) UNLESS LEVEL>=2 FAULT(40,0) IF NMDECS(LEVEL)&1#0 NMDECS(LEVEL)=NMDECS(LEVEL)!X'11';! NO MORE DECS AND IN ONCOND IF STACK=0 THEN START SAVE AUX STACK DISP=AUXSBASE(LEVEL) PSF1(LSS,2,DISP); ! SAVE TOP OF AUX STACK PSF1(ST,1,DISP+12) FINISH GRUSE(ACCR)=0 PSF1(CPSR,1,N+8) PLABEL=PLABEL-1 JJJ=PLABEL ENTER JUMP(15,JJJ,B'10'); ! JUMP ROUND ON BODY ! P=P+2; JJ=0; ! SET UP A BITMASK IN JJ UNTIL A(P-1)=2 CYCLE; ! UNTIL NO MORE NLIST KK=A(P) FAULT2(26,KK,0) UNLESS 1<=KK<=14 JJ=JJ!1<<(KK-1) P=P+2 REPEAT KK=CA; PGLA(4,4,ADDR(CA)) RELOCATE(GLACA-4,KK,1); ! ENTRY ADDRESS IN PLT ONWORD(LEVEL)=JJ<<18!(GLACA-4) FORGET(-1) PSF1(ST,1,N); ! STORE EVENT,SUBEVENT&LINE PSF1(MPSR,1,N+8) ONINF(LEVEL)=N; N=N+12 IF STACK=0 THEN START PSF1(LSS,1,DISP+12); ! RESET AUX STACK TOP PSF1(ST,2,DISP) FINISH CSTART(0,3) NMDECS(LEVEL)=NMDECS(LEVEL)!!X'10';! NOT IN ONCOND JJ=ENTER LAB(JJJ,B'111'); ! REPLACE ENVIRONMENT ->CSSEXIT SW(16): FAULT(57,0) UNLESS LEVEL>=2 BEGIN; ! %SWITCH (SWITCH LIST) INTEGER Q,RANGE,KKK,KK,LB,PP,D0,D1,OPHEAD,V,ARRP,R Q=P ARRP=1 IF PARMOPT=0 THEN ARRP=2 UNTIL A(Q)=2 CYCLE; ! UNTIL NO'REST OF SW LIST' P=P+3 P=P+3 WHILE A(P)=1 P=P+4; ! TO P(+') KKK=INTEXP(LB); ! EXTRACT LOWER BOUND P=P+3 KKK=KKK!INTEXP(KK); ! EXTRACT UPPER BOUND RANGE=(KK-LB+1) IF RANGE<=0 OR KKK#0 START FAULT2(38,1-RANGE,FROMAR2(Q+1)) LB=0; KK=10; RANGE=11 FINISH IF GLACA+8-4*LB<0 THEN ARRP=1; ! ZEROETH ELEMENT OFF FRONT PTYPE=X'56'+ARRP<<8; ! WORD LABEL ARRAY PP=P; P=Q+1 UNTIL A(P-1)=2 CYCLE; ! DOWN NAMELIST K=FROM AR2(P) P=P+3 OPHEAD=0; R=LB ! ! SET UP A BIT LIST (96 BITS PER CELL) TO CHECK FOR SWITCH LABELS ! SET TWICE ! UNTIL R>KK CYCLE PUSH(OPHEAD,0,0,0) R=R+96 REPEAT ! ! FOR CHECKING MODE USE A BOUNDED WORD DESCRIPTOR AND WORD SIZE ! ENTRIES PRESET TO "SW LABEL NOT SET". OPTIMISING USE BCI WORD ! ARRAYS WITH BASE SET TO ZEROETH ELEMENT D1=(GLACA+15)&(-8); ! FIRST TABLE ENTRY D0=X'28000000'!RANGE; ! SCALED WORD DES IF ARRP=2 THEN START D0=D0!X'01000000' UNLESS LB=0; ! SET BCI BIT D1=D1-4*LB FINISH PGLA(8,8,ADDR(D0)) SNDISP=GLACA>>2-2; ! WORD PLT DISP RELOCATE(GLACA-4,D1,2); ! RELOCATE RELATIVE TO GLA PUSH(OPHEAD,D1,LB,KK) KFORM=0; ACC=4 J=1; STORE TAG(K,OPHEAD) ! !THE TABLE WILL CONSIST OF RELATIVE DISPLACEMENTS FROM THE TABLE HEAD ! TO THE LABEL POSN. SET ALL TO GO TO PLAB(6) INITIALLY ! V=PLABS(6) CYCLE KKK=LB,1,KK RELOCATE(-1,V,1); ! PLABS(6) RELOCATED BY HD OF CODE REPEAT REPEAT; ! FOR ANY MORE NAMES IN NAMELIST Q=PP; P=Q REPEAT; ! UNTIL A(Q)=2 END;->CSSEXIT ! SW(17): LIST=1; ->CSSEXIT ! SW(12): ! '%OWN' (TYPE)(OWNDEC) BEGIN !*********************************************************************** !* INITIALISED DECLARATION GO INTO THE GLA OR GLA SYMBOL TABLES * !* EXCEPT FOR CONST ARRAYS WHICH GO INTO THE CODE SYMBOL TABLES * !* STRINGS AND ARRAYS HAVE A HEADER IN THE GLA. LPUT ARRANGES * !* FOR THE LOADER TO RELOCATE THE HEADERS. * !* EXTERNALS ARE IDENTICAL WITH OWN BUT ALSO HAVE A DATA EP DEFN * !* IN THE LOAD DATA SO THEY CAN BE FOUND AT LOAD TIME * !* EXTRINSICS HAVE A DATA REFERENCE AND A DUMMY HEADER IN THE GLA * !* THE LOADER USES THE FORMER TO RELOCATE THE LATTER. * !*********************************************************************** ROUTINESPEC CLEAR(INTEGER L) ROUTINESPEC STAG(INTEGER J,DATALEN) ROUTINESPEC XTRACT CONST(INTEGER CONTYPE,CONPREC) ROUTINESPEC INIT SPACE(INTEGER A,B) INTEGER LENGTH,BP,PP,SIGN,CBASE,MODE,UICONST,ICONST,TAGDISP,EPTYPE, C EPDISP,AH1,AH2,AH3,AH4,AD,FNAM,FINF,SPOINT,CONSTSFOUND,CPREC,C EXTRN,NNAMES,MARK,LPUTP,MARKER1,LB,CTYPE,CONSTP,FORMAT, C PTSIZE,DIMEN,SACC,TYPEP LONGREAL RCONST,LRCONST OWNLONGREAL ZERO=0 STRING(255) SCONST,NAMTXT INTEGERNAME STPTR LPUTP=5; STPTR==USTPTR; ! NORMAL CASE GLA SYMBOLTABLES ! FAULT(40,0) %IF NMDECS&1#0 EXTRN=A(P+1) IF EXTRN>=4 THEN EXTRN=0; ! CONST & CONSTANT->0 LITL=EXTRN IF LITL<=1 THEN LITL=LITL!!1 KFORM=0; SNDISP=0 CONSTS FOUND=0 IF EXTRN=0 THEN LPUTP=4 AND STPTR==SSTL P=P+3; CBASE=0 MODE=A(P-1); ! MODE =1 FOR NORMAL OWNS ->RECORD IF MODE>1; ! MODE =2 FOR OWN RECORDS CLT; ! MODE =3 FOR OWN RECORD ARRAYS IF A(P)=1 THEN CQN(P+1) ELSE ARR=1 AND NAM=0 IF TYPE=5 AND ACC=0=NAM THEN FAULT(70,0) AND ACC=2 ROUT=0; PACK(PTYPE) -> NON SCALAR IF ARR#0 AND NAM=0 P=P+1 UNTIL A(MARK)=2 CYCLE; ! UNTIL <RESTOFOWNDEC> NULL MARK= P+1+FROM AR2(P+1) NNAMES=1 PP=P+3; P=PP+2; ! PP ON FIRST NAME' WHILE A(P)=1 CYCLE NNAMES=NNAMES+1 P=P+3 REPEAT P=P+1; ! P ON CONST' ! ! OBTAIN THE INITIAL CONSTANT,ITS TYPE(CTYPE) AND SIGN(SIGN) ! ICONST=0; UICONST=0 RCONST=0; LRCONST=0; SCONST="" SIGN=3; CTYPE=TYPE; CONSTSFOUND=0; CPREC=PREC IF NAM#0 THEN CTYPE=1 AND CPREC=5 ! IF A(P)=1 THEN START; ! CONSTANT GIVEN P=P+1 XTRACT CONST(CTYPE,CPREC) FINISH ! UNTIL NNAMES=0 CYCLE; ! DOWN <NAMELIST> J=0; K=FROM AR2(PP) NAMTXT=STRING(DICTBASE+WORD(K)) IF NAM#0 THEN START; ! OWNNAMES AND ARRAYNAMES IF EXTRN=3 THEN FAULT2(46,0,K); ! NO EXTRINSIC NAMES UICONST=X'FFFF'!PREC<<27 PGLA(8,ACC,ADDR(UICONST)) TAGDISP=GLACA-ACC; EPDISP=TAGDISP FINISH ELSE START IF TYPE=5 THEN START; ! STRING QQ=STPTR; AD=ADDR(SCONST) IF EXTRN=3 THEN START; ! EXTRINSIC STRINGS AH3=0; AH2=PREC<<27!ACC; ! DUMMY STRING HEADER FINISH ELSE START LPUT(LPUTP,ACC,QQ,AD) IF INHCODE=0; ! O/P STRING STPTR=(STPTR+ACC+3)&(-4) AH3=QQ; AH2=3<<27!ACC FINISH PGLA(8,8,ADDR(AH2)) TAGDISP=GLACA-8 IF EXTRN=3 THEN GXREF(NAMTXT,2,2<<24!ACC,TAGDISP+4) C ELSE RELOCATE(TAGDISP+4,AH3,LPUTP) EPTYPE=5; EPDISP=QQ; ! DATA IN GLA SYMBOL TABLES FINISH ELSE START; ! INTEGER & REAL IF EXTRN=3 THEN START; ! EXTRINSICS PTYPE=PTYPE!1<<10; ! EXTRINSICS VIA PTR AH2=PREC<<27; AH3=0 PGLA(8,8,ADDR(AH2)) TAGDISP=GLACA-8 GXREF(NAMTXT,2,2<<24!ACC,TAGDISP+4) FINISH ELSE START; ! OWN,EXTERNAL&CONST IF TYPE=2 THEN START AD=ADDR(RCONST) FINISH ELSE START; ! INTEGER VARIABLES AD=ADDR(ICONST)+4-ACC FINISH IF EXTRN#0 THEN C PGLA(ACC,ACC,AD); ! PUT CONSTANT INTO GLA TAGDISP=GLACA-ACC; ! OFFSET OF VAR FOR TAGS EPDISP=TAGDISP; ! AND FOR ENTRY DEFN EPTYPE=2; ! DATA IN ADRESSABLE GLA FINISH FINISH FINISH STAG(TAGDISP,ACC) IF EXTRN=0=NAM START; ! CONST = LITERAL REPLACE2(TAGS(K),INTEGER(AD&(-4)));! BYTES! IF PREC=6 THEN REPLACE3(TAGS(K),INTEGER(AD+4)) IF PREC=7 THEN REPLACE3(TAGS(K),CONSTP) FINISH PP=PP+3 NNAMES=NNAMES-1 REPEAT P=MARK REPEAT ->BEND RECORD: ! <XOWN>'%RECORD'<NAMELIST> !*********************************************************************** !* NO INITIALISATION OF OWN RECORDS ALLOWED SO THEY ARE ALL * !* CLEARED TO ZERO. * !*********************************************************************** MARKER1=P+1+FROM AR2(P+1); ! TO FORMAT NAME FNAM=FROM AR2(MARKER1) COPYTAG(FNAM) FINF=TCELL IF PTYPE#4 THEN FAULT(62,FNAM) AND ->BEND PTYPE=X'133'!LITL<<14 KFORM=FINF; UNPACK IF MODE=3 THEN FORMAT=2-A(P) AND P=P+2 AND ->RECIN P=P+1; BP=ACC; ! SIZE OF RECORD FROM FORMAT PTYPE=X'33'; J=0 IF A(P-1)#3 THEN CQN(P-1) AND PACK(PTYPE) P=P+1; PTSIZE=ACC; ! SIZE OF HOLE FOR POINTER UNTIL A(P)=2 CYCLE P=P+1; K=FROM AR2(P) NAMTXT=STRING(DICTBASE+WORD(K)) IF NAM#0 THEN START; ! OWNNAMES AND ARRAYNAMES IF EXTRN=3 THEN FAULT2(46,0,K); ! NO EXTRINSIC NAMES UICONST=X'FFFF'!PREC<<27 PGLA(8,PTSIZE,ADDR(UICONST)) EPTYPE=2 TAGDISP=GLACA-PTSIZE; EPDISP=TAGDISP FINISH ELSE START IF EXTRN=3 THEN START; ! EXTRINISIC PTYPE=PTYPE!X'400'; ! FORCE NAM=1 (IE VIA POINTER) AH2=X'18000000'+BP AH3=0 PGLA(8,8,ADDR(AH2)) TAGDISP=GLACA-8 GXREF(NAMTXT,2,2<<24!BP,TAGDISP+4); ! RELOCATE BY EXTERNAL FINISH ELSE START EPDISP=(GLACA+15)&(-8) AH3=EPDISP AH2=X'18000000'+BP; ! TOP WORD OFDESRCIPTOR PGLA(8,4,ADDR(AH2)); ! ADDED 18MAR76 TO FIX BUG RELOCATE(-1,AH3,2); ! PUT DISP INTO GLA TAGDISP=EPDISP; ! AND RELOCATE REL APPROPIATE AREA EPTYPE=2; ! DATA IN GLA TABLES I=0; ICONST=0 WHILE I<BP CYCLE PGLA(4,4,ADDR(ICONST)) I=I+4 REPEAT FINISH FINISH ACC=BP; ! ACC TO SIZE OF RECORD STAG(TAGDISP,BP) P=P+2 REPEAT ->BEND NONSCALAR: ! OWN AND OWNRECORD ARRAYS !*********************************************************************** !* OWN ARRAYS CAN BE INITIALISED BUT ONLY ONE ARRAY CAN BE * !* DECLARED IN A STATEMENT.(THANK HEAVENS!) * !* OWN RECORD ARRAYS ARE CLEARED TO ZERO * !*********************************************************************** P=P+1 FORMAT=2-A(P) RECIN: PP=P+1; P=P+3; NNAMES=1 K=FROM AR2(PP) NAMTXT=STRING(DICTBASE+WORD(K)) IF TYPE>=3 THEN BP=ACC ELSE BP=BYTES(PREC) SACC=ACC; TYPEP=PTYPE AH4=12+DOPE VECTOR(TYPE,BP,0,K,QQ,LB) SNDISP=AH4-12; ! DV DISP (+TOP BIT FLAG) IF SNDISP=-1 THEN SNDISP=0; ! BUM DOPE VECTOR SNDISP=(SNDISP&X'3FFFF')>>2; ! AS WORD DISPLACEMENT DIMEN=J; ! SAVE NO OF DIMENESIONS ACC=SACC; PTYPE=TYPEP; UNPACK IF LB=0 AND J=1 AND TYPE<=3 THEN C ARR=2 AND PACK (PTYPE) LENGTH=QQ//BP; ! NO OF ELEMENTS SPOINT=STPTR IF MODE#3 AND FORMAT=0 THEN START; ! NOT A RECORD ARRAY IF A(P)=1 THEN P=P+1 AND INIT SPACE(QQ,LENGTH) FINISH IF CONSTS FOUND=0 THEN START; ! NO CONSTANTS GIVEN ! SO CLEAR AN AREA TO ZERO CONSTS FOUND=LENGTH CLEAR(QQ) UNLESS LENGTH<1 OR EXTRN=3 OR FORMAT#0 FINISH ELSE START FAULT2(49,0,K) IF EXTRN=3 OR FORMAT#0 FINISH IF EXTRN=3 THEN EPDISP=0 ELSE EPDISP=SPOINT ! ! OUTPUT AN ARRAYHEAD INTO THE GLA RELATIVE TO THE START OF THE SYMBOL- ! TABLES IN WHICH THE ARRAY RESIDES. ! J=DIMEN; ! RESET DIMENSIONS AFTER INITTING IF TYPE<=2 THEN AH1=PREC<<27!LENGTH ELSE AH1=3<<27!1<<25!QQ AH1=AH1!(1-PARMARR)<<24; ! SET BCI IF BASE TO BE SHIFTED IF PREC=4 THEN AH1=X'58000002' AH2=EPDISP AH3=5<<27!3*J; ! DV DESPTR = WORD CHKD IF TYPE<=3 AND PARMARR=0=FORMAT AND PARMCHK=0 C AND J=1 THEN AH2=AH2-BP*LB PGLA(8,16,ADDR(AH1)) TAGDISP=GLACA-16 IF EXTRN=3 THEN START; ! EXTRINSIC ARRAYS GXREF(NAMTXT,2,2<<24!QQ,TAGDISP+4); ! RELOCATE ADDR(A(FIRST)) FINISH ELSE START RELOCATE(TAGDISP+4,AH2,LPUTP);! RELOCATE ADDR(A(FIRST)) FINISH RELOCATE(TAGDISP+12,AH4,1); ! RELOCATE DV POINTER AH4=(AH4<<1>>3)!X'80000000' NOTE CREF(AH4!(TAGDISP+12)>>2<<16,(AH4&X'FFFF')<<2) EPTYPE=5; ! DATA IN GLA SYMBOL TABLES STAG(TAGDISP,QQ) -> BEND ROUTINE INIT SPACE(INTEGER SIZE,NELS) !*********************************************************************** !* P IS TO FIRST ENTRY FOR CONSTLIST * !* MAP SPACE ONTO WORKFILE END TO GIVE SANE ERROR MESSAGE IF * !* THERE WAS NOT ENOUGH SPACE * !*********************************************************************** INTEGER RF,I,K,ELSIZE,AD,SPP,LENGTH,SAVER,WSIZE,WRIT BYTEINTEGERARRAYNAME SP IF SIZE>4096 THEN WSIZE=4096 ELSE WSIZE=SIZE BYTEINTEGERARRAYFORMAT SPF(0:WSIZE+256) SAVER=R; R=R+WSIZE+256 IF R>ARSIZE THEN FAULT(102,0) SP==ARRAY(ADDR(A(SAVER)),SPF) IF TYPE=1 THEN AD=ADDR(ICONST)+4-ACC IF TYPE=2 THEN AD=ADDR(RCONST) IF TYPE=5 THEN AD=ADDR(SCONST) SPP=0; WRIT=0 ELSIZE=SIZE//NELS UNTIL A(P-1)=2 CYCLE XTRACT CONST(TYPE,PREC) IF A(P)=1 START; ! REPITITION FACTOR P=P+1 IF INTEXP(RF)#0 THEN FAULT(44,CONSTS FOUND) AND RF=1 P=P+1 FINISH ELSE RF=1 AND P=P+2 FAULT(44,CONSTS FOUND) IF RF<=0 CYCLE I=RF,-1,1 CYCLE K=0,1,ELSIZE-1 IF CONSTS FOUND<=NELS THEN C SP(SPP)=BYTE INTEGER(AD+K) AND SPP=SPP+1 REPEAT CONSTS FOUND=CONSTS FOUND+1 IF SPP>=4096 START; ! EMPTY BUFFER LPUT(LPUTP,SPP,STPTR+WRIT,ADDR(SP(0))) IF INHCODE=0 WRIT=WRIT+SPP SPP=0 FINISH REPEAT REPEAT; ! UNTIL P<ROCL>=%NULL IF CONSTS FOUND#NELS THEN FAULT(45,CONSTS FOUND) STPTR=(STPTR+3)&(-4) LENGTH=(SIZE+3)&(-4) LPUT(LPUTP,LENGTH-WRIT,STPTR+WRIT,ADDR(SP(0))) IF INHCODE=0 STPTR=STPTR+LENGTH R=SAVER END ROUTINE CLEAR(INTEGER LENGTH) STPTR=(STPTR+3)&(-4) LENGTH=(LENGTH+3)&(-4) LPUT(LPUTP,LENGTH,STPTR,0)IF INHCODE=0 STPTR=STPTR+LENGTH END ROUTINE STAG(INTEGER J,DATALEN) IF EXTRN=2 THEN C LPUT(14,EPTYPE<<24!DATALEN,EPDISP,ADDR(NAMTXT)) RBASE=CBASE STORE TAG(K,J) RBASE=RLEVEL END ROUTINE XTRACT CONST(INTEGER CONTYPE,CONPREC) !*********************************************************************** !* P POINTS TO P<+'> OF <+'><OPERNAD><RESTOFEXPR> AND IS UPDATED* !* THE CONST IS CONVERTED TO REQUIRED FORM AND IF INTEGER * !* IS LEFT IN ICONST, IF REAL IN RCONST AND IF STRING IN SCONST * !*********************************************************************** INTEGER LENGTH,STYPE,SPREC,SACC,CPREC,MODE,I STYPE=PTYPE; SACC=ACC;! MAY BE CHANGED IF CONST IS EXPR IF CONTYPE=5 THEN START CTYPE=5 IF A(P)=4 AND A(P+1)=2 AND A(P+2)=X'35' AND C A(P+A(P+7)+8)=2 START SCONST=STRING(ADDR(A(P+7))) LENGTH=A(P+7) P=P+A(P+7)+9 FINISH ELSE START FAULT(44,CONSTS FOUND); SCONST="" LENGTH=0; P=P-3; SKIP EXP FINISH FINISH ELSE START MODE=CONPREC<<4!CONTYPE IF CONPREC<5 THEN MODE=CONTYPE!X'50' CONSTP=CONSTEXP(MODE) IF CONSTP=0 THEN FAULT(41,0) AND CONSTP=ADDR(ZERO); ! CANT EVALUATE EXPT CTYPE=TYPE; CPREC=PREC IF CTYPE=1 THEN START ICONST=INTEGER(CONSTP) IF CONPREC=6 THEN UICONST=ICONST AND ICONST= C INTEGER(CONSTP+4) FINISH ELSE START RCONST=LONGREAL(CONSTP) IF CONPREC=7 THEN START; ! LONGLONGS UNALIGNED IN AR CYCLE I=0,1,15 BYTEINTEGER(ADDR(RCONST)+I)=BYTEINTEGER(CONSTP+I) REPEAT FINISH FINISH FINISH PTYPE=STYPE; UNPACK; ACC=SACC ! ! FAULT ANY OBVIOUS ERRORS IE:- ! CONSTANT FOR EXTRINSIC OR INCOMPATIBLE TYPE OR STRING TOO LONG ! IF EXTRN=3 OR (CTYPE=5 AND LENGTH>=ACC) C OR (CONTYPE=1 AND ((CONPREC=3 AND ICONST>255) OR C (CONPREC=4 AND ICONST>X'FFFF'))) THEN C FAULT(44,CONSTS FOUND) END BEND: END; ->CSSEXIT SW(18): ABORT SW(10): BEGIN; ! %RECORD (RDECLN) !*********************************************************************** !* RECORDS ARE ALLOCATED AT COMPILE TIME WHEN POSSIBLE * !* SEE CRFORMAT FOR ACTION ON RECORD FORMAT DECLARATIONS * !*********************************************************************** INTEGER MODE,RECL,ALLOC,FNAM,FINF,NAME,OPHEAD P=P+1; MODE=A(P); SNDISP=0 IF MODE=1 THEN START; ! DEAL WITH FORMAT NAME=FROM AR2(P+1); P=P+3 CRFORMAT(OPHEAD); K=NAME PTYPE=4; J=0 KFORM=OPHEAD STORE TAG(K,OPHEAD) ->BEND FINISH P=P+1; MARKER=P+FROM AR2(P) FNAM=FROM AR2(MARKER); ! FORMAT NAME COPY TAG(FNAM) FINF=TCELL IF TYPE#4 THEN START FINF=DUMMY FORMAT ACC=4; FAULT(62,FNAM) FINISH RECL=ACC IF MODE=2THEN START; ! '%RECORDSPEC' COPY TAG(FROM AR2(P+2)) IF A(P+4)=1 AND TYPE=4 START; ! SPEC FOR FORMAT ELEMENT P=P+5 Q=DISPLACEMENT(TCELL) UNPACK FINISH IF TYPE=3 AND NAM=1 AND FROM3(TCELL)&X'FFFF'=0 START REPLACE3(TCELL,FINF!K<<16) REPLACE2(TCELL,SNDISP<<16!RECL) FINISH ELSE FAULT(63,0) FINISH ELSE START; ! RECORD DECLARATION FAULT(57,0) UNLESS LEVEL>=2 FAULT(40,0) IF NMDECS(LEVEL)&1#0 TYPE=3; PREC=3; ROUT=0 IF A(P+2)=1 THEN START; ! SIMPLE RECORD AND RECORDNAMES ALLOC=ACC; CQN(P+3) ACC=ALLOC; P=P+4 DECLARE SCALARS(1,FINF) FINISH ELSE START; ! ARRAYS OF RECORDS NAM=0 Q=2-A(P+3); P=P+4; ! Q=1 FOR ARRAY FORMAT SET LINE DECLARE ARRAYS(Q,FINF) FINISH FINISH BEND: END;->CSSEXIT ! SW(19): ! '*' (UCI) (S) FAULT(57,0) UNLESS LEVEL>=2 BEGIN ROUTINESPEC CIND INTEGER FNAME,ALT,OPCODE,FORM,H,Q,MASK,FILLER SWITCH SW(1:5),F(1:3),POP(1:6),TOP(1:4) ALT=A(P+1); P=P+2 OPCODE=CALL ->SW(ALT) SW(1):SW(2): FNAME=FROM AR2(P) COPY TAG(FNAME) FAULT(33,FNAME) UNLESS ROUT=NAM=0 AND ARR=0 AND C PREC>4 AND I=RBASE AND TYPE#7 IF ALT=1 THEN PSF1(ST,1,K) ELSE C GET IN ACC(ACCR,BYTES(PREC)>>2,0,LNB,K) ->EXIT SW(3): ! PUT (HEX HALFWORD) TYPE=A(P) PREC=TYPE>>4; TYPE=TYPE&7 FAULT(32,0) UNLESS TYPE=1 AND PREC<6 IF PREC=5 THEN P=P+2 PLANT(FROM AR2(P+1)) ->EXIT SW(5): ! CNOP CNOP(A(P),A(P+1)) ->EXIT SW(4): ! ASSEMBLER FORM=A(P); ! FORM=PRIMARY,SECONDARY OR 3RY OPCODE=A(P+1) P=P+2; ->F(FORM) F(1): ! ALL PRIMARY FORMAT INSTRUCTIONS ALT=A(P); P=P+1 ->POP(ALT) POP(1): ! LABELNAME FNAME=FROM AR2(P); P=P+2 ENTER JUMP(OPCODE<<24!3<<23,FNAME,0) ->EXIT POP(2): ! DIRECT SYMBOLIC CIND POPI: PSORLF1(OPCODE,ACCESS,AREA,DISP) ->EXIT POP(3): ! INDIRECT SYMBOLIC CIND ACCESS=4-A(P); P=P+1 ->POPI POP(4): ! DR SYMBOLICALLY MODIFIED CIND; ACCESS=1; ->POPI POP(5): ! (DR) & (DR+B) ACCESS=4-A(P); AREA=7 DISP=0; P=P+1 ->POPI POP(6): ! B ACCESS=0 AREA=7; DISP=0; ->POPI F(2): ! SECONDARY (STORE-TO STORE)FORMAT MASK=0; FILLER=0; Q=0; FNAME=0 H=2-A(P) IF H=0 THEN FNAME=FROM AR2(P+1)-1 AND P=P+2 FAULT(32,0) UNLESS 0<=FNAME<=127 ALT=A(P+1); P=P+2 IF ALT=1 THEN START Q=1 MASK=FROM AR2(P) FILLER=FROM AR2(P+2) P=P+4 FAULT(32,0) UNLESS 0<=MASK!FILLER<=255 FINISH PF2(OPCODE,H,Q,FNAME,MASK,FILLER) ->EXIT F(3): ! TERTIARY FORMAT MASK=FROM AR2(P) ALT=A(P+2) FAULT(32,0) UNLESS 0<=MASK<=15 P=P+3; ->TOP(ALT) TOP(1): ! LABEL FNAME=FROM AR2(P); P=P+2 ENTER JUMP(OPCODE<<24!MASK<<21,FNAME,0) ->EXIT TOP(2): ! SYMBOLIC OPERAND CIND FAULT(32,0) IF AREA>=6 IF AREA=LNB OR AREA=XNB OR AREA=CTB THEN DISP=DISP//4 TOPI: PF3(OPCODE,MASK,AREA,DISP) ->EXIT TOP(3): ! (DR) & (DR+B) DISP=0; AREA=8-A(P) P=P+1; ->TOPI TOP(4): ! (DR+N) DISP=FROM AR2(P); P=P+2 AREA=1; ->TOPI ROUTINE CIND !*********************************************************************** !* COMPILE A SYMBOLIC OPERAND BY SETTING ACCESS,AREA &DISP * !*********************************************************************** INTEGER ALT,AFN,FN0,FN1,FN2,FN3,JJ,D,CTYPE,CPREC SWITCH SW(1:4) AFN=ADDR(FN0) ALT=A(P); ACCESS=0 P=P+1; ->SW(ALT) SW(1): ! (=')(PLUS')(ICONST) P=P+1; ! PAST (=') D=A(P); CTYPE=A(P+1) CPREC=CTYPE>>4; CTYPE=CTYPE&7 IF CPREC=4 THEN FN0=FROM AR2(P+2) ELSE START CYCLE JJ=0,1,BYTES(CPREC)-1 BYTEINTEGER(AFN+JJ)=A(P+JJ+2) REPEAT FINISH P=P+2+BYTES(CPREC) IF D=2 THEN START IF CTYPE=2 THEN FN0=FN0!!X'80000000' ELSE START IF CPREC=6 THEN LONGINTEGER(AFN)=-LONGINTEGER(AFN) C ELSE FN0=-FN0 FINISH FINISH CNST: ->LIT UNLESS CTYPE=1 AND CPREC<=5 AND C X'FFFE0000'<=FN0<=X'1FFFF' AREA=0; DISP=FN0 RETURN LIT: FAULT(32,0) UNLESS 1<=CTYPE<=2 AND 5<=CPREC<=7 STORE CONST(DISP,BYTES(CPREC),AFN) AREA=PC; ACCESS=0 RETURN SW(2): ! (NAME)(OPTINC) FN0=FROM AR2(P); P=P+2 COPY TAG(FN0) IF (LITL=1 AND ARR=0) START CTYPE=TYPE; CPREC=PREC ALT=TAGS(FN0) FROM123(ALT,D,FN0,FN1) IF CPREC=7 THEN AFN=FN1 ->CNST FINISH IF TYPE>=6 OR TYPE=4 OR C (ROUT=1 AND NAM=0) THEN FAULT(33,FN0) AND RETURN IF ROUT=1 THEN K=FROM1(K) AREA=LNB IF I#RBASE THEN AREA=SET XORYNB(XNB,I) ALT=A(P); D=FROM AR2(P+1) IF ALT=1 THEN K=K+D IF ALT=2 THEN K=K-D P=P+1; P=P+2 IF ALT<=2 DISP=K; RETURN SW(3): ! '('(REG)(OPTINC)')' AREA=A(P)+1; ALT=A(P+1); P=P+2 DISP=0 D=FROM AR2(P) IF ALT=1 THEN DISP=D IF ALT=2 THEN FAULT(32,0) IF AREA=PC THEN DISP=CA+2*DISP ELSE DISP=4*DISP P=P+2 UNLESS ALT=3 RETURN SW(4): ! '%TOS' AREA=6; DISP=0 END EXIT: GRUSE(ACCR)=0 GRUSE(DR)=0 GRUSE(BREG)=0 GRUSE(XNB)=0 IF OPCODE=CALL OR OPCODE=LXN OR OPCODE=JLK C OR OPCODE=OUT GRUSE(CTB)=0 IF OPCODE=CALL OR OPCODE=LCT OR OPCODE=JLK C OR OPCODE=OUT END ->CSSEXIT SW(20): ! '%TRUSTEDPROGRAM' COMPILER=1 IF PARMARR=0 AND PARMCHK=0; ->CSSEXIT SW(21): ! '%MAINEP'(NAME) KK=FROM AR2(P+1) FAULT(58,0) UNLESS CPRMODE=0 MAINEP<-STRING(DICTBASE+WORD(KK)) ->CSSEXIT ROUTINE CRFORMAT(INTEGERNAME OPHEAD) !*********************************************************************** !* CONVERTS A RECORDFORMAT STATEMENT TO A LIST HEADED BY OPHEAD * !* FORMAT OF AN ENTRY. * !* S1=SUBNAME<<20!PTYPE<<4!J * !* S2,S3=4 16 BIT DISPLACEMENTS D2,ACC,D1,KFORM * !* NORMALLY D1=RECORD RELATIVE DISPLACEMENT AND ACC=LMAX(STRINGS)* !* FOR ARRAYS D2=FIRST ELEMENT DISPLACEMENT AND D1=DISPLACEMENT * !* OF RECORD RELATIVE ARRAYHEAD IN THE GLA * !* KFORM IS ONLY USED FOR RECORDS AND POINTS TO THE FORMAT * !* ON EXIT ACC HAS THE RECORD SIZE ROUNDED UP TO THE BOUNDARY * !* REQUIRED BY ITS LARGEST COMPONENT * !*********************************************************************** INTEGER D1,D2,NLIST,FORM,RL,MRL,UNSCAL,SC,DESC,FN,INC,Q,R,A0,A1,A2, C DV,RFD,LB,OB,TYPEP,SACC SWITCH RFEL(1:5) ROUTINESPEC SN(INTEGER Q) ROUTINESPEC ROUND NLIST=0; OPHEAD=0; FORM=0; ACC=0; OB=0 MRL=0; INC=0; ! INC COUNTS DOWN RECORD NEXT: ROUT=0; LITL=0; NAM=0; RFD=A(P) IF RFD<=2 THEN P=P+1 AND CLT ->RFEL(RFD) RFEL(1): ! (TYPE) (QNAME')(NAMELIST) CQN(P); P=P+1 PACK(PTYPE); D2=0 RL=3 IF NAM=0 AND 3<=PREC<=4 THEN RL=PREC-3 AGN: ROUND ; J=0 UNTIL A(P-1)=2 CYCLE D1=INC; SN(P) P=P+3; INC=INC+ACC REPEAT P=P+RFD>>2<<1; ! EXTRA 2 FOR RECORDS TO SKIP FORMAT TRY END: -> END IF A(P)=2 P=P+1; -> NEXT RFEL(2):RFEL2: ! (TYPE)%ARRAY(NAMELIST)(BPAIR) Q=P; ARR=1; PACK(PTYPE) IF TYPE<=2 THEN UNSCAL=0 AND SC=PREC C ELSE UNSCAL=1 AND SC=3 IF PREC=4 THEN DESC=X'58000002' ELSE C DESC=SC<<27!UNSCAL<<25!(1-PARMARR)<<24 UNTIL A(P-1)=2 CYCLE; ! UNTIL <RESTOFARRAYLIST> NULL P=P+3 UNTIL A(P-1)=2 TYPEP=PTYPE; SACC=ACC DV=DOPE VECTOR(TYPE,ACC,0,FROMAR2(Q),R,LB)+12 ! DOPE VECTOR INTO SHAREABLE S.T. ACC=SACC; PTYPE=TYPEP; UNPACK IF TYPE=5 OR (TYPE=1 AND PREC=3) THEN RL=0 ELSE RL=3 ROUND UNTIL A(Q-1)=2 CYCLE; ! HEAD INTO GLA FOR EACH ARRAY A0=R; IF UNSCAL=0 THEN A0=A0//ACC IF PREC=4 THEN A0=0; ! STRING DESCRIPTORS ! A0=A0!DESC; A1=INC IF TYPE<=3 AND PARMARR=0=PARMCHK AND J=1 THEN C A1=A1-LB*ACC A2=5<<27!3*J PGLA(4,16,ADDR(A0)) D1=GLACA-16 RELOCATE(D1+12,DV,1); ! RELOCATE DV POINTER NOTE CREF(X'80000000'!(DV<<1>>3)!(D1+12)>>2<<16, C (DV&X'FFFF')<<2) D2=INC SN(Q); INC=INC+R Q=Q+3 REPEAT P=P+1; Q=P REPEAT P=P+2 IF RFD=5 -> TRY END RFEL(3): ! %RECORD (%ARRAY) %NAME TYPE=3; PREC=3; NAM=1 ARR=2-A(P+1); P=P+2 PACK(PTYPE); D2=0 RL=3; ACC=8+8*ARR FORM=0 ->AGN RFEL(4): ! RECORDS IN RECORDS RFEL(5): ! RECORDARRAYS IN RECORDS Q=P+FROM AR2(P+1)+1 FN=FROM AR2(Q) COPY TAG(FN); ! COPY FORMAT TAG & SET ACC FAULT(62,FN) UNLESS PTYPE=4 TYPE=3; PREC=3; FORM=TCELL IF RFD=4 THEN START PTYPE=X'33'; P=P+3; D2=0 RL=3; ->AGN FINISH P=P+3; ->RFEL2 END: ! FINISH OFF RL=MRL; ROUND ACC=INC; ! SIZE ROUNDED APPROPRIATELY FAULT(98,0) UNLESS INC<=X'7FFF' CLEAR LIST(NLIST) RETURN ROUTINE SN(INTEGER Q) !*********************************************************************** !* CHECK THE SUBNAME HAS NOT BEEN USED BEFORE IN THIS FORMAT * !* AND ENTER IT WITH ITS DESCRIPTORS INTO THE LIST. * !*********************************************************************** FNAME=FROM AR2(Q) FAULT2(61,0,FNAME) UNLESS FIND(FNAME,NLIST)=-1 BINSERT(OPHEAD,OB,FNAME<<20!PTYPE<<4!J,D2<<16!ACC,D1<<16!FORM) PUSH(NLIST,0,FNAME,0) END ROUTINE ROUND MRL=RL IF RL>MRL INC=INC+1 WHILE INC&RL#0 END END; ! OF ROUTINE CRFORMAT INTEGERFN DISPLACEMENT(INTEGER LINK) !*********************************************************************** !* SEARCH A FORMAT LIST FOR A SUBNAME * !* A(P) HAS ENAME--LINK IS HEAD OF RFORMAT LIST. RESULT IS DISP * !* FROM START OF RECORD * !*********************************************************************** RECORDNAME FCELL,PCELL,LCELL(LISTF) INTEGER RR,II,ENAME,CELL ENAME=A(P)<<8+A(P+1); CELL=0 IF LINK#0 THEN START; ! CHK RECORDSPEC NOT OMITTED FCELL==ASLIST(LINK); ! ONTO FORMAT TAG CELL LINK=FCELL_S3&X'7FFF'; ! LINK TO SIDE CHAIN CELL=LINK; II=-1; ACC=-1 WHILE LINK>0 CYCLE LCELL==ASLIST(LINK) IF LCELL_S1>>20=ENAME START; ! RIGHT SUBNAME LOCATED TCELL=LINK RR=LCELL_S1 SNDISP=LCELL_S2 K=LCELL_S3 J=RR&15; PTYPE=RR>>4&X'FFFF' ACC=SNDISP&X'FFFF'; SNDISP=SNDISP&X'FFFF0000'//X'10000' KFORM=K&X'FFFF'; K=K>>16 IF LINK#CELL START; ! NOT TOP CELL OF FORMAT PCELL_LINK=LCELL_LINK LCELL_LINK=CELL FCELL_S3=FCELL_S3&X'FFFF0000'!LINK FINISH; ! ARRANGING LIST WITH THIS SUBNAME ! AT THE TOP RESULT=K FINISH PCELL==LCELL LINK=LCELL_LINK REPEAT FINISH FAULT(65,ENAME) IF CELL>0 THEN C PUSH(ASLIST(CELL)_LINK,ENAME<<20!7<<4,0,0) PTYPE=7; TCELL=0 RESULT=-1 END INTEGERFN COPY RECORD TAG(INTEGERNAME SUBS) !*********************************************************************** !* PRODUCE PTYPE ETC FOR A COMPOUND NAME BY CHAINING DOWN ONE * !* ONE OR MORE RECORD FORMAT LISTS. ON EXIT RESULT =0 IF NO * !* SUBNAME FOUND OR SUBNAME IS OF TYPE RECORD WITH NO FURTHER * !* SUBNAME ATTACHED. RESULT#0 IF BONE-FIDE SUBNAME LOCATED * !* ON ENTRY KFORM HAS POINTER TO THE (FIRST ) FORMAT LIST AND * !* P POINTS TO THE A.R. ENTRY FOR (FIRST) ENAME * !*********************************************************************** INTEGER Q,FNAME SUBS=0 UNTIL TYPE#3 CYCLE FNAME=KFORM P=P+2; SKIP APP RESULT=0 IF A(P)=2 OR FNAME<=0; ! NO (FURTHER) ENAME SUBS=SUBS+1 P=P+1; Q=DISPLACEMENT (FNAME) UNPACK REPEAT RESULT=Q+1; ! GIVES 0 IF SUBNAME NOT KNOWN END ROUTINE CRNAME(INTEGER Z,REG,MODE,BS,AR,DP,INTEGERNAME NAMEP) !*********************************************************************** !* DEAL WITH RECORD ELEMENT NAMES.Z AS FOR CNAME.CLINK=TAGS(RN) * !* MODE=ACCESS FOR RECORD(NOT THE ELEMENT!) * !* ON EXIT BASE,AREA & DISP POINT TO REQUIRED ELEMENT * !* RECURSIVE CALL IS NEEDED TO DEAL WITH RECORDS IN RECORDS * !* DEPTH SHEWS RECURSIVE LEVELS- NEEDED TO AVOID MIS SETTING * !* REGISTER IN USE IF RECORDNAME IN RECORD HAS THE SAME NAME AS * !* A GENUINE RECORD NAME. * !*********************************************************************** INTEGER DEPTH,FNAME ROUTINESPEC CENAME(INTEGER MODE,FNAME,BS,AR,DP,XD) DEPTH=0 FNAME=KFORM; ! POINTER TO FORMAT IF ARR=0 OR (Z=6 AND A(P+2)=2) START; ! SIMPLE RECORD IF A(P+2)=2 THEN P=P+3 ELSE NO APP CENAME(MODE,FNAME,BS,AR,DP,0) FINISH ELSE START CANAME(ARR,BS,DP) CENAME(ACCESS,FNAME,BASE,AREA,DISP,0) FINISH; RETURN ! ROUTINE CENAME(INTEGER MODE,FNAME,BS,AR,DP,XD) !*********************************************************************** !* FINDS OUT ABOUT SUBNAME AND ACTS ACCORDINGLY.MOSTLY ACTION * !* CONSISTS OF UPPING XD BY OFFSET OF THE SUBNAME BUT IS VERY * !* HAIRY FOR RECORDS IN RECORDS ETC * !* MODE IS ACCESS FOR THE RECORD * !*********************************************************************** ROUTINESPEC FETCH RAD ROUTINESPEC LOCALISE(INTEGER SIZE) INTEGER Q,QQ,D,C,W DEPTH=DEPTH+1 IF A(P)=2 THEN START; ! ENAME MISSING ACCESS=MODE; AREA=AR; XDISP=XD BASE=BS; DISP=DP; ! FOR POINTER IF Z<14 THEN START; ! NOT A RECORD OPERATION UNLESS 3<=Z<=4 OR Z=6 START; ! ADDR(RECORD) FAULT(64,0); BASE=RBASE; AREA=-1 DISP=0; ACCESS=0; PTYPE=1; UNPACK FINISH FINISH RETURN FINISH P=P+1; ! FIND OUT ABOUT SUBNAME Q=DISPLACEMENT(FNAME); ! TCELL POINTS TO CELL HOLDING UNPACK; ! INFO ABOUT THE SUBNAME IF Q=-1=ACC OR PTYPE=7 START; ! WRONG SUBNAME(HAS BEEN FAULTED) P=P+2; SKIP APP; P=P-3 ACCESS=0; BASE=RBASE; DISP=0; AREA=-1 RETURN FINISH NAMEP=(A(P)<<8!A(P+1))<<16!NAMEP; ! NAMEP=-1 UNALTERED ! ->AE IF ARR=1; ! ARRAYS INCLUDING RECORDARRAYS IF A(P+2)=2 THEN P=P+3 ELSE NO APP IF TYPE<=2 OR TYPE=5 OR C (TYPE=3 AND A(P)=2 AND (3<=Z<=4 OR Z=6)) START ACCESS=MODE+4+4*NAM; BASE=BS; AREA=AR; DISP=DP; XDISP=XD+Q RETURN FINISH ! ! NOW CODING BECOMES HAIRY:- STILL LEFT ARE ! A) RECORDS IN RECORDS Q POINTS TO SECONDARY RECORD ! B) RECORDNAMES IN RECORDS Q HAS OFF-SET OF A POINTER ! C) RECORDARRAYNAMES IN RECORDS Q HAS OFF-SET A HEADER IN RECORD ! D) RECORDARRAYS IN RECORDS NOT YET ALLOWED ! Q WOULD HAVE OFF-SET OF A RECORD RELATIVE HEADER IN THE GLA ! XD=XD+Q NAMEP=-1 IF NAM=1 THEN START IF MODE=0 START DP=DP+XD; XD=0; MODE=2 FINISH ELSE START LOCALISE(8); ! PICK UP RECNAME DESCR &STCK AR=AREA; DP=DISP; BS=BASE FINISH FINISH CENAME(MODE,KFORM,BS,AR,DP,XD) RETURN AE: ! ARRAYS AND ARRAYNAMES AS ELEMEN FROM123(TCELL,Q,SNDISP,K) ACC=SNDISP&X'FFFF'; SNDISP=SNDISP&X'FFFF0000'//X'10000' KFORM=K&X'FFFF'; K=K>>16 C=ACC; D=SNDISP; Q=K; QQ=KFORM IF (Z=6 OR Z=12) AND A(P+2)=2 START; ! 'GET ARRAYHEAD' CALL P=P+3 IF NAM=1 THEN START ACCESS=MODE+8; BASE=BS AREA=AR; DISP=DP; XDISP=XD+Q RETURN FINISH ! ! PASSING AN ARRAY IN A RECORD BY NAME MUST CONSTRUCT PROPER ARRAYHEAD ! FROM THE RECORD RELATIVE ONE AT Q(GLA) ! NAMEP=-1 FETCH RAD AREA=-1; DISP=Q BASE=0; ACCESS=0; CREATE AH(1) FINISH ELSE START; ! ARRAY ELEMENTS IN RECORDS NAMEP=-1 IF NAM=1 THEN START; ! ARRAYNAMES-FULLHEAD IN RECORD XD=XD+Q LOCALISE(16); ! MOVE HEAD UNDER LNB CANAME(3,BASE,DISP); ! ARRAY MODE SETS DISP,AREA&BASE FINISH ELSE START; ! ARRAY RELATIVE HEAD IN GLA IF MODE=0 OR MODE=2 START IF MODE=0 THEN W=DP-4 ELSE W=DP+4 FINISH ELSE START FETCH RAD; ! RECORD ADDR TO ACC GET WSP(W,1) PSF1(ST,1,W); XD=0 BS=RBASE FINISH CANAME(3,0,Q); ! RECORD REL ARRAY ACCESS ! CAN RETURN ACCESS=1 OR 3 ONLY IF PARMARR=0=PARMCHK AND ACCESS=3 AND C (PREC=3 OR TYPE>=3) START PSORLF1(ADB,0,AREA CODE2(BS),W) PSF1(ADB,0,XD) UNLESS XD=0 GRUSE(BREG)=0 FINISH ELSE START GET IN ACC(DR,2,0,AREA CODE,Q) PSORLF1(INCA,0,AREA CODE2(BS),W) IF ACCESS=1 THEN ACCESS=2 AND AREA=7 C AND XD=XD+NUMMOD*BYTES(PREC) PSF1(INCA,0,XD) UNLESS XD=0 FORGET (DR) AREA=7; DISP=0; ! AND ACCESS = 2 OR 3 ONLY IF TYPE=3 AND A(P)=1 START; ! WILL BE A FURTHER CALL ! ON ROUTINE CENAME GET WSP(DISP,2) PSF1(STD,1,DISP) AREA=LNB; BASE=RBASE FINISH FINISH FINISH IF TYPE=3 THEN CENAME(ACCESS,QQ,BASE,AREA,DISP,0) FINISH RETURN ROUTINE FETCH RAD !*********************************************************************** !* SET ACC TO 32 BIT ADDRESS OF RECORD. * !*********************************************************************** ACCESS=MODE+4 AREA=AR; BASE=BS DISP=DP; XDISP=XD NAMEOP(4,ACCR,4,-1) END ROUTINE LOCALISE(INTEGER SIZE) !*********************************************************************** !* REMOVES A DESCRIPTOR OR ARRAYHEAD FROM A RECORD AND STORES * !* IT IN A TEMPORARY UNDER LNB. * !*********************************************************************** INTEGER HOLE ACCESS=MODE+4 AREA=AR; BASE=BS; DISP=DP XDISP=XD NAMEOP(2,ACCR,SIZE,-1) GET WSP(HOLE,SIZE>>2) PSF1(ST,1,HOLE) MODE=2; AREA=LNB BASE=RBASE; DISP=HOLE; XD=0 END; ! OF ROUTINE LOCALISE END; ! OF ROUTINE CENAME END; ! OF ROUTINE CRNAME ROUTINE CSTREXP(INTEGER MODE,REG) !*********************************************************************** !* PLANT IN-LINE CODE FOR CONCATENATION. A WORK AREA UNDER * !* BASE REGISTER COVER IS USUALLY REQUIRED. THE CURRENT LENGTH * !* OF STRING IN THE WORK AREA IS KEPT IN A REGISTER (BREG) * !* WHICH IS PROTECTED THROUGH THE NORMAL INTERMEDIATE-RESULT * !* MECHANISMS. * !* ON ENTRY:- * !* MODE=0 NORMAL. WK AREA NOT USED FOR ONE OPERAND EXPSSNS * !* MODE=1 STRING MUST GO TO WORK AREA * !* (AND TO COME) * !* MODE=3 CONCATENATE INTO LHS OF =ASSNMNT (E.G. A=B.C) * !* MODE=4 OPTIMISE S=S.T BY NOT COPYING S * !* 2**4 BIT OF MODE IS SET IF WK-AREA NOT TO BE FREED ON EXIT * !* ON EXIT:- * !* BASE,DISP & INDEX DEFINE RESULT * !* VALUE#0 %IF RESULT IN A WORK AREA(CCOND MUST KNOW) * !* STRINGL SET IF STRING LENGTH KNOWN. STRFNRES DEFINES LENREG * !*********************************************************************** INTEGER PP,WKAREA,DOTS,REXP,ERR,CLEN,KEEPWA,FNAM INTEGERFNSPEC STROP(INTEGER REG) KEEPWA=MODE&16; MODE=MODE&15 PP=P; STRINGL=0; FNAM=0; WKAREA=0 REXP=2-A(P+1+FROM AR2(P+1)); ! =0 %IF ONE OPERAND EXP -> NORMAL UNLESS A(P+3)=4 AND REXP=0 AND MODE=0 -> SIMPLE IF A(P+4)=2 -> NORMAL UNLESS A(P+4)=1 ! COPY TAG(FROM AR2(P+5)) ! %IF PTYPE=SNPT %THEN PTYPE=TSNAME(K) ! -> NORMAL %UNLESS ROUT=0 ; ! BEWARE OF MAP=FN ! -> NORMAL %IF PARMARR=1 %AND(ARR#0 %OR A(P+7)=1) SIMPLE: P=P+4 ERR=STROP(REG) -> ERROR UNLESS ERR=0 VALUE=WKAREA P=P+1; STRFNRES=0 RETURN ERROR: FAULT2(ERR,0,FNAM) BASE=RBASE; DISP=0 VALUE=0; ACCESS=0 P=PP; SKIP EXP RETURN NORMAL: CLEN=0; P=P+3; ! LENGTH OF CONSTANT PART ERR=72; ->ERROR UNLESS A(P)=4 P=P+1 GET WSP(WKAREA,268); ! GET NEXT OPERAND DOTS=0; ! NO OPERATORS YET NEXT: STRINGL=0 ERR=STROP(DR); ! GET NEXT OPERAND -> ERROR UNLESS ERR=0 IF REGISTER(ACCR)#0 THEN BOOT OUT(ACCR) PSF1(LB,0,WKAREA); ! BYTE DISP FROM LNB PPJ(0,19+DOTS); ! TO SUBROUTINE 19 OR 20 IF A(P)=2 THEN -> TIDY; ! NO MORE OPERATIONS ERR=72; -> ERROR UNLESS A(P+1)=CONCOP; ! CONCATENATE DOTS=DOTS!1 P=P+2; -> NEXT TIDY: ! FINISH OFF VALUE=WKAREA P=P+1; ! PAST REST OF EXPRN RETURN WSP(WKAREA,268) IF KEEPWA=0 STRINGL=0 RETURN INTEGERFN STROP(INTEGER REG) !*********************************************************************** !* DEALS WITH OPERAND FOR CONCATENATION. RETURN RESULT=0 FOR * !* VALID OPERAND OTHERWISE AN ERROR NUMBER. * !*********************************************************************** INTEGER CTYPE,VAL,MODE MODE=A(P); ! ALTERNATIVE OF OPERAND RESULT=75 IF MODE>2 IF MODE#1 THEN START CTYPE=A(P+1); ! GET CONST TYPE & LOSE AMCK FLAGS IF CTYPE=X'35' THEN START STRINGL=A(P+6) DISP=FROM AR4(P+2) P=P+STRINGL+7 FINISH ELSE RESULT=71 PF1(LDRL,0,PC,STRLINK) PSF1(INCA,0,DISP) IF DISP#0 IF STRINGL#1 THEN START IF STRINGL<=63 THEN PSF1(LDB,0,STRINGL) C ELSE PF1(LDB,2,7,0); ! ((DR)) FINISH GRUSE(DR)=0 IF REG=ACCR THEN COPY DR FINISH ELSE START P=P+1; ! MUST CHECK FIRST REDUCE TAG; ! SINCE CNAME ONLY LOADS STRINGS ! AND LONGINTS TO DR! IF 5#TYPE#7 THEN FNAM=FROMAR2(P) AND RESULT=71 CNAME(2,REG) STRINGL=0 IF ROUT#0 AND NAM<=1 START; ! WAS FUNCTION NOT MAP IF WKAREA=0 AND KEEPWA#0 THEN C WKAREA=STRFNRES ELSE RETURN WSP(STRFNRES,268) FINISH FINISH RESULT=0 END; ! OF INTEGERFN STROP END; ! OF ROUTINE CSTREXP ROUTINE CRES (INTEGER LAB) !********************************************************************** !* COMPILES A RESOLUTION E.G A->B.(C).D.(E).F AND JUMPS TO LAB * !* ON FAILURE. (LAB=0 FOR UNCONDITIONAL RESOLUTION TO PERM ON * !* FAILURE ). * !* THE METHOD IS TO CALL A SUBROUTINE PASSING 3 PARAMS:- * !* P1 POINTS TO LHS(A) * !* P2 STRING TO CONTAIN FRAGMENT (PASSED BY NAME) * !* P3 THE EXPRESSION PASSED AS DESCRIPTOR * !* SUBROUTINE TRIES TO PERFORM THE RESOLUTION AND SETS THE * !* CONDITION CODE =8 IF IT SUCCEEDS. * !* * !* ON ENTRY LHS IS DEFINED BY DESCRIPTOR REG. * !* P POINTS TO P(+') OF RHS DEFINED AS (+')(OPERAND)(RESTOFEXP) * !* * !$ THE ROUTINE IS COMPACT BUT DIFFICULT TO FOLLOW (OR ALTER) * !* THE TIME IN PERM IS LARGE SO IT IS NOT WORTHWHILE TO PERSUE * !* CODE EFFICIENCY TOO INDUSTRIOUSLY . * !********************************************************************** INTEGER P1,P2,SEXPRN,W,LAST,ERR,FNAM RECORD R(RD) LAST=0; FNAM=0; ! =1 WHEN END OF EXPRNSN FOUND SEXPRN=0; ! RESOLUTION(BRKTD) EXPRESSNS ERR=74; ! NORMAL CRES FAULT PSF1(INCA,0,1); ! TO FIRST CHAR P1=P; P=P+3 ->RES IF A(P)=4; ! LHS MUST BE A STRING ! BUT THIS CHECKED BEFORE CALL ERR=72 ERROR: FAULT2(ERR,0,FNAM) P=P1; SKIP EXP; RETURN RES: P=P+1; ! TO P(OPERAND) PSF1(PRCL,0,4) IF SEXPRN=0 THEN W=STD ELSE W=ST PF1(W,0,TOS,0) IF A(P)=3 THEN PSF1(LSD,0,0) AND GRUSE(ACCR)=0 ELSE START; ! B OMITTED ->ERROR UNLESS A(P)=1; ! P(OPERAND)=NAME P=P+1; P2=P CNAME(3,ACCR) IF TYPE#5 THEN ERR=71 AND FNAM=FROMAR2(P2) AND ->ERROR IF A(P+1)#CONCOP THEN ERR=72 AND ->ERROR P=P+2 FINISH PF1(ST,0,TOS,0); ! B (OR DUMMY) TO P2 ->ERROR UNLESS A(P)=3; ! P(OPERAND)='('(EXPR)')' SEXPRN=SEXPRN+1; P=P+1 CSTREXP(0,DR); ! TO REGISTER DR ! PF1(STD,0,TOS,0) PSF1(RALN,0,11) PPJ(-1,16) ! DEAL WITH CC#8 IE RESLN FAILED IF LAB#0 THEN ENTER JUMP(7,LAB,B'11') ELSE PPJ(7,12) ! -> END IF A(P)=2 IF A(P+1)#CONCOP THEN ERR=72 AND ->ERROR ->ERROR UNLESS A(P+2)=1 P2=P+1; P=P2+1 P=P+3 AND SKIP APP UNTIL A(P)=2 IF A(P+1)=1 THEN P=P2 AND ->RES P1=P+1 REGISTER(ACCR)=1 OLINK(ACCR)=ADDR(R) R_PTYPE=1; R_XB=ACCR R_FLAG=9 P=P2+2; CNAME(1,DR) IF R_FLAG#9 THEN PF1(LSD,0,TOS,0) REGISTER(ACCR)=0 PF1(STUH,0,BREG,0) PF1(LUH,0,BREG,0) PF2(MVL,0,0,0,0,0) IF ROUT#0 OR NAM#0 THEN PPJ(0,18); ! ASSNMNT CHECK (Q.V) PF2(MV,1,1,0,0,UNASSPAT&255) GRUSE(ACCR)=0 IF PARMARR=1 START PSF1(USH,0,8) PSF1(USH,0,-40) PPJ(36,9) FINISH P=P1 END: P=P+1 END ROUTINE SAVE AUX STACK !*********************************************************************** !* COPY AUX STACK DESCRPTR & POINTER INTO CURRENT STACK FRAME * !* FIVE WORDS ARE USED FOR THIS PURPOSE:- * !* 1&2 HOLD AUX STACK DESCRIPTOR * !* 3 HOLDS VALUE AT BLK ENTRY FOR USE AT EXIT * !* 4 HOLDS STACKTOP VALUE AFTER ALL ARRAY DECLNS(FOR %ONS) * !* 5 HOLD STACKLIMIT FOR CHECKING AT ARRAY DECLARATIONS * !* THE LATTER IS OMITTED INPARM=OPT * !*********************************************************************** INTEGER XYNB, DR0, DR1 IF AUXST=0 THEN START; ! FIRST REF PUT REF IN PLT DR0=X'30000001'; DR1=0 PGLA(8,8,ADDR(DR0)) AUXST=GLACA-8 GXREF(AUXSTEP,2,X'02000008',AUXST+4) FINISH IF AUXSBASE(LEVEL)=0 START XYNB=SET XORYNB(-1,-1) PF1(LD,2,XYNB,AUXST) IF PARMOPT#0 THEN START PF1(LSS,1,0,2); ! PICK UP STACKTOP PSF1(ST,1,N+16) FINISH PF1(LSS,2,7,0) PSF1(STD,1,N) PSF1(ST,1,N+8) AUXSBASE(LEVEL)=N; N=N+16 IF PARMOPT#0 THEN N=N+4 GRUSE(DR)=0; GRUSE(ACCR)=11; GRINF1(ACCR)=0 FINISH END ROUTINE RESET AUX STACK !*********************************************************************** !* IF ANY ARRAYS HAVE BEEN PUT ON THE AUXSTACK THEN UNDECLARE * !*********************************************************************** IF AUXSBASE(LEVEL)#0 START PSF1(LB,1,AUXSBASE(LEVEL)+8) PSF1(STB,2,AUXSBASE(LEVEL)) GRUSE(BREG)=0 FINISH END ROUTINE RT EXIT !*********************************************************************** !* THIS ROUTINE COMPILES CODE FOR ROUTINE EXIT(IE '%RETURN') * !*********************************************************************** RESET AUX STACK PSF1(EXIT,0,-X'40') END ROUTINE CLAIM ST FRAME(INTEGER AT,VALUE) !*********************************************************************** !* FILL ASF INSTN IN RT ENTRY SEQUENCE TO CLAIM THE STACKFRAME * !*********************************************************************** INTEGER INSTR, WK WK=AT>>18; ! BYTES CLAIMED BY ENTRY SEQ AT=AT&X'3FFFF'; ! ADRR OF ASF INSTRN INSTR=(ASF+12*PARMCHK)<<24!3<<23!(VALUE-WK+3)>>2 PLUG(1,AT,INSTR,4) END ROUTINE CEND (INTEGER KKK) !*********************************************************************** !* DEAL WITH ALL OCCURENCES OF '%END' * !* KKK=PTYPE(>=X'1000') FOR ROUTINES,FNS AND MAPS * !* KKK=0 FOR ENDS OF '%BEGIN' BLOCKS * !* KKK=1 FOR '%ENDOFPROGRAM' * !* %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,JJ,BIT ROUTINESPEC DTABLE(INTEGER LEVEL) SET LINE UNLESS KKK=2 FORGET(-1) BIT=1<<LEVEL ! ! NOW PLANT AN ERROR EXIT FOR FNS AND MAPS - CONTROL SHOULD BE RETURNED ! VIA %RESULT= AN SHOULD NEVVER REACH THE %END INSTRUCTION ! IF KKK&X'3FFF'>X'1000' AND COMPILER=0 AND LAST INST=0 C THEN PPJ(15,10); ! RUN FAULT 11 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) I=I>>24 IF J&X'FFFF'#0 THEN START J=J&X'FFFF' IF 0<KP<=MAX ULAB THEN FAULT2(11,FROM3(J),KP) CLEAR LIST(J) FINISH ELSE START IF I=0 AND KP<MAX ULAB THEN WARN(3,KP) FINISH REPEAT ! CYCLE JJ=0,1,4 CLEAR LIST(AVL WSP(JJ,LEVEL));! RELEASE TEMPORARY LOCATIONS REPEAT ! DTABLE(LEVEL); ! OUTPUT DIAGNOSTIC TABLES ! ! CLEAR DECLARATIONS - POP UP ANY GLOBAL NAMES THAT WERE REDECLARED ! DESTROY SIDE CHAINS FOR ROUTINES,FORMATS AND SWITCHES ! ! ! NOW CLAIM THE STACK FRAME BY FILING THE ASF IN THE BLOCK ENTRY CODING ! NMAX=(NMAX+7)&(-8) IF KKK=2 THEN RETURN IF KKK>=X'1000' OR KKK=1 THEN CLAIM ST FRAME(SET(RLEVEL),NMAX) ! ! NOW PLANT THE BLOCK EXIT SEQUENCE ! IF KKK&X'3FFF'=X'1000' AND LAST INST=0 THEN RT EXIT PPJ(15,21) IF KKK=1 AND LAST INST=0; ! %STOP AT %ENDOFPROGRAM IF KKK=0 THEN START; ! BEGIN BLOCK EXIT IF PARMTRACE=1 THEN START; ! RESTORE DIAGS POINTERS PSF1(LD,1,12) DIAG POINTER(LEVEL-1) PSF1(STD,1,12) FINISH IF STACK#0 START JJ=NMDECS(LEVEL)>>14 IF JJ#0 THEN START; ! ARRAYS TO BE UNDECLARED PF1(STSF,0,TOS,0) PF1(LSS,0,TOS,0) PSF1(ISB,1,JJ) PSF1(USH,0,-2) PF1(ST,0,TOS,0) PF1(ASF,0,TOS,0) GRUSE(ACCR)=0 FINISH FINISH ELSE RESET AUX STACK 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 ELSE C FAULT(14,0) AND STOP FINISH LEVEL=LEVEL-1 IF KKK>=X'1000' THEN START RLEVEL=RLEVEL-1 RBASE=RLEVEL FINISH ! ! RESTORE INFORMATION ABOUT THE (NEW) CURRENT LEVEL ! POP(LEVELINF,KP,N,KP) NMAX=N>>16 IF KKK>=X'1000' N=N&X'7FFF' IF KKK=2 THEN CEND(KKK); ! ROUND AGAIN FOR 'ENDOFPROGRAM' ! ! COMPLETE THE JUMP AROUND ALL NON-EXTERNAL ROUTINES EXCEPT WHEN ! %TRUSTEDPROGRAM IS IN OPERATION. ! IF ASL WARN#0 THEN ASL WARN=0 AND EPILOGUE IF KKK>=X'1000' AND COMPILER=0 AND(RLEVEL>0 OR CPRMODE#2)C THEN START JJ=NEXTP+6 UNLESS A(NEXTP+5)=11 AND A(JJ+FROMAR2(JJ))=2 START JJ=ENTER LAB(JROUND(LEVEL+1),0) JROUND(LEVEL+1)=0 FINISH FINISH 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)<<18 ! ENVIRONMENT ! ( TOP 2 BITS OF LANG DEPENDENT HAS LITL FROM PTYPE) ! ( BOTTOM 4 BITS HAVE TEXTUAL LEVEL) ! 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.* !* FOR MAIN PROGRAMS OR EXTERNAL ROUTINES THE 'GLOBAL' VARIABLES * !* (IF ANY) ARE ALSO INCLUDED. * !*********************************************************************** STRING(31) RT NAME STRING(11) LOCAL NAME RECORDNAME LCELL(LISTF) CONSTINTEGER LARRROUT=X'F300' INTEGER DPTR,LNUM,ML,KK,JJ,Q,DEND,BIT,S1,S2,S3,S4,LANGD,II INTEGERARRAY DD(0:500); ! BUFFER FOR SEGMENT OF SST ! ! FILL ALL OUTSTANDING REFERENCES TO THIS DIAGS BLOCK ! BIT=1<<LEVEL LANGD=KKK>>14<<30!LEVEL<<18; ! GET LITL FROM PTYPE WHILE RAL(LEVEL)#0 CYCLE POP(RAL(LEVEL),Q,JJ,KK) PLUG(Q,JJ,KK!SSTL,4) REPEAT PUSH(RAL(LEVEL-1),4,SSTL+4,LANGD) IF PARMTRACE#0 DD(0)=L(LEVEL)<<16!(DIAGINF(LEVEL)) DD(1)=LANGD DD(2)=DISPLAY(RLEVEL)<<16!FLAG(LEVEL)&X'3FFF' ML=M(LEVEL); ! ROUTINE NAME(=0 FOR %BEGIN) LNUM=BYTEINTEGER(DICTBASE+ML); ! LENGTH OF THE NAME DPTR=4; DEND=0 IF LNUM=0 THEN DD(3)=0 ELSE START Q=DICTBASE+ML RT NAME<-STRING(Q); ! FOR RTS MOVE IN 1ST 32 CHARS LNUM=BYTE INTEGER(ADDR(RT NAME)) STRING(ADDR(DD(3)))=RTNAME; ! AND UPDATE POINTER PAST DPTR=DPTR+LNUM>>2; ! ACTUAL NO OF CHARS FINISH DD(DPTR)=ONWORD(LEVEL); ! ON CONDITION WORD DPTR=DPTR+1 JJ=NAMES(LEVEL) WHILE 0<=JJ<X'3FFF' CYCLE LCELL==ASLIST(TAGS(JJ)) ! OBTAIN NEXT NAME FORM DECLNS IF LCELL_S1&X'F000'=0 THEN WARN(2,JJ) ! ! GET ONLY THE MINIMUM OF DETALS NECESSARY ! S1=LCELL_S1; S2=LCELL_S2 S3=LCELL_S3; S4=LCELL_LINK LCELL_LINK=ASL; ASL=TAGS(JJ) TAGS(JJ)=S4&X'3FFFF' PTYPE=S1>>16; TYPE=PTYPE&15 I=S1>>4&15 J=S1&15 K=S3>>16 ! ! ALLOW OWNS (LITL=0) AND EXTERNALS (=2) NOT CONSTS(=1) OR EXTRINSIC(=3) ! IF PARMDIAG#0 AND PTYPE&X'7300'<=X'200' AND DPTR<497 C AND (TYPE=1 OR TYPE=2 OR TYPE=5) START Q=DICTBASE+WORD(JJ); ! ADDRESS OF NAME IF I=0 THEN II=1 ELSE II=0; ! GLA OR LNB BIT DD(DPTR)=PTYPE<<20!II<<18!K 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 IF J=15 AND S2#0 THEN FAULT2(28,0,JJ) ! SPEC&CALLED BUT NO BODY GIVEN IF PTYPE&X'3000'#0 OR TYPE=4 OR TYPE=6 THEN C CLEAR LIST(K) ELSE START IF I#0 AND K>511 AND PTYPE&LARRROUT=0 AND TYPE#7 C THEN WARN(5,JJ) FINISH JJ=S4>>18 REPEAT DD(DPTR)=-1; ! 'END OF SEGMENT' MARK DPTR=DPTR<<2+4 IF PARMTRACE=1 THEN START LPUT(4,DPTR,SSTL,ADDR(DD(0)));! ADD TO SHARABLE SYM TABS SSTL=SSTL+DPTR FINISH END; ! OF ROUTINE DTABLE END ROUTINE MAKE DECS(INTEGER Q) !*********************************************************************** !* Q IS TO AR ENTRY FOR HEAD OF LINKED DECLARATIONS * !*********************************************************************** INTEGER QQ,HEAD,PRIO,COUNT,SL INTEGERNAME THEAD RECORDNAME CELL(LISTF) SL=LINE; QQ=FROM AR4(Q) HEAD=0; COUNT=0 WHILE QQ#0 CYCLE COUNT=COUNT+1 ABORT UNLESS A(QQ+5)=8; ! LINE IS A DECLARATION P=QQ+10; CLT IF PREC=3 OR A(P)#1 OR A(P+1)# 3 START INSERT AT END(HEAD,X'FFFF',QQ,0) IF A(P)=1 FINISH ELSE START PRIO=PREC<<4!TYPE THEAD==HEAD CYCLE CELL==ASLIST(THEAD) IF THEAD=0 OR PRIO<CELL_S1 THEN C PUSH(THEAD,PRIO,QQ,0) AND EXIT THEAD==CELL_LINK REPEAT FINISH QQ=FROM AR4(QQ+6) REPEAT ! ! NOW MAKE THE ORDEREED DECLARATIONS ! FIRST GRAB TWO TEMPORARIES IF SPACE IS LIKELY TO BE TIGHT ! IF COUNT>=7 START GET WSP(QQ,2); ! A DIUBLE WORD IF AVL WSP(1,LEVEL)=0 THEN GET WSP(QQ,1) FINISH WHILE HEAD#0 CYCLE POP(HEAD,PRIO,QQ,COUNT) LINE=FROM AR2(QQ+3) P=QQ+10; CLT ROUT=0; LITL=0 CQN(P+1); P=P+2 DECLARE SCALARS(1,0) REPEAT LINE=SL END ROUTINE DECLARE SCALARS(INTEGER PERMIT,XTRA) !*********************************************************************** !* THIS ROUTINE DECLARES A LIST OF SCALARS FROM INFORMATION * !* IN THE GLOBAL VARIABLES ROUT,NAM,ARR,PREC,TYPE & ACC.IT WORKS * !* OUT ROUNDING FACTORS FOR ITSELF. * !* P POINTS TO THE NAMELIST ON ENTRY AND IS UPDATED. * !*********************************************************************** INTEGER INC,Q,SCHAIN,DMADE,NPARMS,D0,SCAL NAME,TYPEP PACK(PTYPE); J=0 INC=ACC; DMADE=0; SNDISP=0 IF PTYPE=X'33' THEN INC=(INC+3)&(-4) IF NAM#0 AND ROUT=0 AND ARR=0 THEN INC=8 IF NAM>0 AND ARR>0 THEN INC=16 IF PTYPE=X'35' AND ACC=0 THEN FAULT(70,0) IF PERMIT#0 AND (INC=8 OR INC=16) THEN ODD ALIGN IF PTYPE=X'33' OR (PTYPE=X'35' AND PERMIT#0)START D0=X'18000000'+ACC STORE CONST(Q,4,ADDR(D0)) PF1(LDTB,0,PC,Q) GRUSE(DR)=0 FINISH IF PTYPE=X'35' START INC=8 IF PERMIT#0 START PF1(STSF,0,TOS,0) PF1(LDA,0,TOS,0) FINISH FINISH N=(N+3)&(-4) IF PTYPE=X'33' THEN START PSF1(LDA,1,PTR OFFSET(RBASE)) PSF1(INCA,0,N+8) FINISH UNTIL A(P-1)=2 CYCLE; ! DOWN THE NAMELIST DMADE=DMADE+1 SCAL NAME=FROM AR2(P) IF PTYPE=X'31' AND PERMIT=0 THEN N=N+3; ! BYTE PARAMS IF PTYPE=X'41' AND PERMIT=0 THEN N=N+2 SCHAIN=N KFORM=XTRA IF ROUT=1 THEN START TYPEP=PTYPE; ! CHANGED BY CFPLIST! Q=P P=P+3 UNTIL A(P-1)=2; ! TO FPP CFPLIST(SCHAIN,NPARMS) P=Q J=13 KFORM=NPARMS; ! NO OF PARAMS OF FORMAL ACC=N; ! DISPLACEMENT TO MIDCELL PTYPE=TYPEP; UNPACK FINISH P=P+3 IF PTYPE=X'33' THEN START PSF1(STD,1,N) N=N+8; SCHAIN=N IF A(P-1)=1 THEN PSF1(INCA,0,INC+8) FINISH IF PTYPE=X'35' AND PERMIT#0 START PSF1(STD,1,N) IF A(P-1)=1 THEN PSF1(INCA,0,(ACC+3)&(-4)) ELSE START Q=((ACC+3)>>2)*DMADE PSF1(ASF+12*PARMCHK,0,Q) IF PARMCHK#0 THEN PPJ(0,4) FINISH FINISH STORE TAG(SCAL NAME,SCHAIN) N=N+INC REPEAT N=(N+3)&(-4) IF PERMIT#0; ! NO ROUNDING AMONG PARAMS END INTEGERFN DOPE VECTOR(INTEGER TYPEP,ELSIZE,MODE,IDEN, C 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<BPAIR> * !* 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) * !* MODE=0 DV MUST BE CONST, MODE#0 CAN BE DYNAMIC * !* P TO ALT (ALWAYS=1) OF P(BPAIR) * !*********************************************************************** INTEGER I, JJ, K, ND, D, UNSCAL, M0, HEAD, NOPS, TYPEPP, PIN, PTR RECORDNAME LCELL(LISTF) INTEGERARRAY LBH,LBB,UBH,UBB(0:12) INTEGERARRAY DV(0:39); ! ENOUGH FOR 12 DIMENSIONS ND=0; NOPS=0; TYPEPP=0; PIN=P IF TYPEP>2 OR (TYPEP=1 AND PREC=4)C THEN UNSCAL=1 AND M0=ELSIZE C ELSE UNSCAL=0 AND M0=1 UNTIL A(P)=2 CYCLE ND=ND+1; P=P+4 LBH(ND)=0; LBB(ND)=0 UBB(ND)=0; UBH(ND)=0 TORP(LBH(ND),LBB(ND),NOPS) P=P+3 TYPEPP=TYPEPP!TYPE TORP(UBH(ND),UBB(ND),NOPS) TYPEPP=TYPEPP!TYPE REPEAT P=P+1 ->NONCONST UNLESS TYPEPP=1 AND NOPS&X'40040000'=0 ! ! NOW ONE CAN WORK OUT AND FILL IN THE TRIPLES ! PTR=1 CYCLE D=ND,-1,1 K=3*D EXPOP(LBH(PTR),ACCR,NOPS,X'251') EXPOPND_D=0 AND FAULT(41,0) UNLESS C EXPOPND_FLAG<=1 AND EXPOPND_PTYPE=X'51' DV(K)=EXPOPND_D DV(K+1)=M0 EXPOP(UBH(PTR),ACCR,NOPS,X'251') EXPOPND_D=10 AND FAULT(41,0) UNLESS C EXPOPND_FLAG<=1 AND EXPOPND_PTYPE=X'51' JJ=EXPOPND_D M0=M0*(JJ-DV(K)+1) FAULT2(38,1-M0,IDEN) UNLESS JJ>=DV(K) DV(K+2)=M0 PTR=PTR+1 REPEAT ! IF UNSCAL=0 THEN M0=M0*ELSIZE IF ND=1 THEN LB=DV(3) ASIZE=M0 DV(2)=ASIZE DV(1)=12 DV(0)=5<<27!3*ND; ! DESPTR FOR DV K=3*ND+2 J=ND; ! DIMENSIONALITY FOR DECLN 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) WAYOUT: CYCLE D=ND,-1,1 ASLIST(LBB(D))_LINK=ASL ASL=LBH(D) ASLIST(UBB(D))_LINK=ASL ASL=UBH(D) REPEAT RESULT =I NONCONST: ! NOT A CONST DV J=ND; I=-1 LB=0; ASIZE=ELSIZE IF MODE=0 THEN FAULT(41,0) ELSE P=PIN ->WAYOUT END ROUTINE DECLARE ARRAYS(INTEGER FORMAT, FINF) !*********************************************************************** !* FORMAT=1 FOR 'ARRAYFORMAT' =0 OTHERWISE * !* FINF>0 FOR RECORD FORMAT INFORMATION =0 OTHERWISE * !* P IS AT P<ADECLN> IN * !* * !* P<ADECLN>=<NAMELIST> <BPAIR> <RESTOFDECLN> * !* P<BPAIR> = '('<EXPR>':'<EXRR><RESTOFBP>*')' * !* * !* ARRAYS WITH CONSTANT BOUNDS HAVE THEIR D-V IN THE SST * !* 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, D0, D1, PTYPEP, C ARRP, NN, ND, II, JJ, QQ, R, CDV, UNSCAL, DESC, SC, C LWB, PTYPEPP, JJJ, JJJJ, ADJ IF STACK#0 AND FLAG(LEVEL)=0=NMDECS(LEVEL)>>14 START PSF1(STSF,1,N) NMDECS(LEVEL)=NMDECS(LEVEL)!(N<<14) N=N+4 FINISH IF STACK=0 THEN SAVE AUX STACK ARRP=2*FORMAT+1; ARR=ARRP; PACK(PTYPEP) ELSIZE=ACC IF TYPE>2 OR (TYPE=1 AND PREC=4)C THEN UNSCAL=1 AND SC=3 C ELSE UNSCAL=0 AND SC=PREC DESC=SC<<27!UNSCAL<<25!(1-PARMARR)<<24;! ARRAY DESCRIPTOR SKELETON IF PREC=4 THEN DESC=X'58000002' START:NN=1; P=P+1; ! NO OF NAMES IN NAMELIST PP=P; CDV=0; PTYPEPP=PTYPEP P=P+3 AND NN=NN+1 WHILE A(P+2)=1 P=P+3 DVDISP=DOPE VECTOR(TYPE,ELSIZE,1,FROMAR2(PP),TOTSIZE,LWB) ND=J ->CONSTDV UNLESS DVDISP=-1 ! NORMAL CASE - PLANT CODE TO SET UP DOPE-VECTOR AT RUN TIME DVF=0; TOTSIZE=X'FFFF' 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,ADDR(D0)) PF1(LD,0,PC,JJ) PSF1(STD,1,DVDISP) GRUSE(DR)=0 IF UNSCAL=0 THEN JJ=1 ELSE JJ=ELSIZE PSF1(LSS,0,JJ); ! M1 THE FIRST MULTIPLIER GRUSE(ACCR)=0 CYCLE II=ND,-1,1 P=P+1 QQ=DVDISP+12*II; ! TRIPLE FOR IITH DIMENSION PSF1(ST,1,QQ+4); ! STORE MULTIPLIER CSEXP(ACCR,X'51'); ! LOWER BOUND IF ND=1 AND PTYPEP&7<=3 AND FORMAT=0 AND GRUSE(ACCR)=5 C AND GRINF1(ACCR)=0 THEN PTYPEPP=PTYPEPP+256 PSF1(ST,1,QQ); ! STORED IN DV CSEXP(ACCR,X'51'); ! UPPER BOUND PSF1(ISB,1,QQ) GRUSE(ACCR)=0 IF COMPILER=0 OR PARMARR#0 START PF3(JAF,6,0,3); ! JUMP UNLESS NEGATIVE PSF1(LSS,0,-1); ! SET UP -1 (ENSURES 0 ELEMENTS FINISH PSF1(IAD,0,1); ! CONVERTED TO RANGE PSF1(IMY,1,QQ+4); ! RANGE*MULTIPLIER PSF1(ST,1,QQ+8); ! AND STORED IN DV REPEAT P=P+1 IF UNSCAL=0 AND ELSIZE#1 THEN PSF1(IMY,0,ELSIZE) PSF1(ST,1,DVDISP+8) SNDISP=0; ! DV NOT AVAILABLE AT COMPILETIME ->DECL CONSTDV: ! ONE DIMENSION - CONSTANT BOUNDS DVF=1; CDV=1 IF ND=1 AND LWB=0 AND PTYPEP&15<=3 C AND FORMAT=0 THEN PTYPEPP=PTYPEP+256 ! SET ARR=2 IF LWB=ZERO SNDISP=(DVDISP&X'FFFFFF')>>2 DECL: ! MAKE DECLN - BOTH WAYS J=ND ODD ALIGN PTYPE=PTYPEPP; UNPACK IF DVF#0 THEN START; ! ARRAY IS STRING OF LOCALS R=TOTSIZE IF UNSCAL=0 THEN R=R//ELSIZE D0=DESC D0=D0!R UNLESS PREC=4 STORE CONST(D1,4,ADDR(D0)) PF1(LB,0,PC,D1) FINISH ELSE START STORE CONST(D1,4,ADDR(DESC)) PF1(LB,0,PC,D1) PSF1(ADB,1,DVDISP+20) UNLESS PREC=4 FINISH IF DVF#0 THEN QQ=PC ELSE QQ=LNB PSORLF1(LDRL,0,QQ,DVDISP) GRUSE(BREG)=0; GRUSE(DR)=0 CYCLE JJJ=0,1,NN-1; ! DOWN NAMELIST PSF1(STB,1,N+16*JJJ); ! ARRAY BOUND PSF1(STD,1,N+8+16*JJJ); ! DV POINTER REPEAT IF PARMARR=0 AND PARMCHK=0 AND ND=1 AND TYPE<=3 C AND PTYPEPP&X'F00'#X'200' THEN ADJ=1 ELSE ADJ=0 CYCLE JJJ=0,1,NN-1; ! DOWN NAMELIST IF ADJ#0 START; ! ADJUST DESC IF STACK#0 START; ! ARRAY ON AUTOMATIC STACK PF1(STSF,0,BREG,0); ! CURRENT SF TO B IF DVF#0 THEN PSF1(SBB,0,LWB*ELSIZE) ELSE START IF ELSIZE=1 THEN PSF1(SBB,1,DVDISP+12) ELSESTART PSF1(SLB,1,DVDISP+12) PSF1(MYB,0,ELSIZE) PF1(SLB,0,TOS,0) PF1(SBB,0,TOS,0) FINISH FINISH PSF1(STB,1,N+4) GRUSE(BREG)=0 FINISH ELSE START; ! ARRAY ON AUX STACK IF DVF#0 START; ! CONST DOPE VECTOR UNLESS GRUSE(ACCR)=11 START PSF1(LSS,2,AUXSBASE(LEVEL)) GRUSE(ACCR)=11; GRINF1(ACCR)=0 FINISH JJJJ=LWB*ELSIZE-GRINF1(ACCR) PSF1(ISB,0,JJJJ) UNLESS JJJJ=0 GRINF1(ACCR)=LWB*ELSIZE FINISH ELSE START; ! DYNAMIC ARRAYS IF GRUSE(ACCR)=11 AND GRINF1(ACCR)=0 AND C ELSIZE=1 THEN PSF1(ISB,1,DVDISP+12) ELSESTART PSF1(LSS,1,DVDISP+12) PSF1(IMY,0,ELSIZE) UNLESS ELSIZE=1 PSF1(IRSB,2,AUXSBASE(LEVEL)) FINISH GRUSE(ACCR)=0 FINISH PSF1(ST,1,N+4) FINISH FINISH ELSE START; ! NO ADJUSTMENT OF DESCRPT IF STACK#0 THEN PSF1(STSF,1,N+4) ELSE START PSF1(LSS,2,AUXSBASE(LEVEL)) UNLESS GRUSE(ACCR)=11 C AND GRINF1(ACCR)=0 PSF1(ST,1,N+4) GRUSE(ACCR)=11; GRINF1(ACCR)=0 FINISH FINISH ACC=ELSIZE; ! RESET ACC AFTER DV CMPLD KFORM=FINF; ! FORMAT INFORMATION K=FROM AR2(PP+3*JJJ) STORE TAG(K,N) CLAIM AS IF FORMAT = 0 N=N+16 REPEAT P=P+1; ! PAST REST OF ARRAYLIST IF A(P-1)=1 THEN ->START RETURN ROUTINE CLAIM AS !*********************************************************************** !* CLAIM THE SPACE FOR AN ARRAY FROM STACK OR AUX STACK * !*********************************************************************** INTEGER T, B, D,ADJMENT IF STACK=1 THEN START; ! FROM AUTOMATIC STACK IF CDV=1 THEN START; ! CONSTANT BOUNDS T=(TOTSIZE+3)//4 PSF1(ASF+12*PARMCHK,0,T); ! ASF OR LB PPJ(0,4) IF PARMCHK#0 FINISH ELSE START; ! DYNAMIC BOUNDS IF PARMCHK=0 AND PTYPEP&7<=2 AND C (ELSIZE=4 OR ELSIZE=8) START PSF1(ASF,1,DVDISP+20); ! SIZE IN ELEMENTS WORD PSF1(ASF,1,DVDISP+20) IF ELSIZE=8 FINISH ELSE START PSF1(LSS,1,DVDISP+8); ! ARRAY SIZE BYTES PSF1(IAD,0,3) IF ELSIZE&3#0 PSF1(USH,0,-2); ! ARRAY SIZE WORDS PF1(ST,0,BREG,0) FORGET(BREG) IF PARMCHK#0 THEN PPJ(0,4) ELSE PF1(ASF,0,BREG,0) FINISH FINISH CHECK STOF FINISH ELSE START UNLESS GRUSE(ACCR)=11 AND (GRINF1(ACCR)=0 OR CDV=1) START PSF1(LSS,2,AUXSBASE(LEVEL)) GRUSE(ACCR)=11; GRINF1(ACCR)=0 FINISH IF CDV=1 THEN START ADJMENT=(TOTSIZE+7)&(-8)+GRINF1(ACCR) IF ADJMENT<X'1FFFF' THEN B=0 AND D=ADJMENT C ELSE START STORE CONST(D,4,ADDR(ADJMENT)) B=PC FINISH IF ADJ=1 AND JJJ#NN-1 AND PARMOPT=0 THEN C GRINF1(ACCR)=ADJMENT ELSE START GRINF1(ACCR)=0 PSORLF1(IAD,0,B,D) UNLESS B=D=0 FINISH FINISH ELSE START B=LNB; D=DVDISP+8 PSF1(IAD,1,D) UNLESS ELSIZE&7=0 START PSF1(IAD,0,7) PSF1(AND,0,-8) FINISH GRINF1(ACCR)=0 FINISH PSF1(ST,2,AUXSBASE(LEVEL)) IF JJJ=NN-1 OR (ADJ=1 AND CDV=0) IF PARMOPT#0 THEN START PSF1(ICP,1,AUXSBASE(LEVEL)+16) PPJ(2,8) FINISH IF PARMCHK#0 START PF1(LDTB,0,PC,PARAM DES(3)) PSORLF1(LDB,0,B,D) PSF1(LDA,1,N+4) PF2(MVL,1,1,0,0,UNASSPAT&255) GRUSE(DR)=0 FINISH FINISH END END ! %ROUTINE TEST NST !!*********************************************************************** !!* SEE IF NAME 'K' HAS BEEN DECLARED BEFORE AT THIS LEVEL * !!*********************************************************************** ! FNAME=K ! FAULT(7,FNAME) %IF FROM1(TAGS(FNAME))>>8&15=LEVEL ! %END ROUTINE CLT !*********************************************************************** !* DEAL WITH PHRASE TYPE AND SET PREC,TYPE & ACC * !* ONLY PROBLEM IS STRING WHICH HAS OPTIONAL MAX LENGTH ALSO * !* P ON PHRASE TYPE AT ENTRY - TO NEXT PHRASE AT EXIT. * !*********************************************************************** CONSTBYTEINTEGERARRAY TYPEFLAG(1:10)= C X'51',X'52',0,X'31',X'35', X'41',0,X'62',X'61',X'72'; INTEGER ALT ALT=A(P) TYPE=TYPEFLAG(ALT) IF TYPE=0 THEN P=P+1 AND TYPE=TYPEFLAG(A(P)+7) PREC=TYPE>>4 TYPE=TYPE&7 PREC=6 IF TYPE=2 AND ALL LONG#0 AND PREC<=5; ! DEAL WITH '%REALSLONG' ACC=BYTES(PREC) IF TYPE=5 THEN START; ! P<TYPE>='%STRING' IF A(P+1)=1 THEN START; ! MAX LENGTH GIVEN P=P+2 ACC=A(P)+1 FINISH ELSE ACC=0 AND P=P+1 FINISH P=P+1 END ROUTINE CQN(INTEGER P) !*********************************************************************** !* SET NAM,ARR & ACC FROM ALTERNATIVE OF PHRASE <QNAME'> * !* P<QNAME'>='%ARRAYNAME','%NAME',<%NULL> * !* P POINTS TO THE ANALYSIS RECORD ENTRY AS IS NOT UPDATED * !*********************************************************************** INTEGER I I=A(P);NAM=0;ARR=0 IF I=1 THEN ARR=1 AND ACC=16; ! ARRAYNAMES IF I<=2 THEN NAM=1; ! ARRAYNAMES & NAMES IF I=2 THEN ACC=8; ! NAMES USE 8-BYTE DESCRIPTOR END ROUTINE CRSPEC (INTEGER M) !*********************************************************************** !* MODE=0 FOR NORMAL ROUTINE SPEC * !* MODE=1 FOR EXTERNAL(ETC) ROUTINE SPECS XREF NEEDED * !* P ON ENTRY TO P(RT) IN (RT)(MARK)(%SPEC')(NAME)(FPP) * !*********************************************************************** INTEGER KK,JJ,TYPEP,OPHEAD,NPARMS STRING(34) XNAME LITL=EXTRN&3 IF A(P)=1 THEN START; ! P<RT>=%ROUTINE TYPEP=LITL<<14!X'1000' P=P+2; ! IGNORING ALT OF P(SPEC') FINISH ELSE START; ! P<RT>=<TYPE><FNORMAP> ROUT=1; ARR=0; P=P+1 CLT; NAM=0 IF A(P)=2 THEN NAM=2; ! 2 FOR MAP 0 FOR FN PACK(TYPEP) P=P+2; ! AGAIN IGNORING ALT OF P(SPEC') FINISH P=P+4; ! PAST HOLE FOR DECLINKS KK=FROM AR2(P) JJ=0 P=P+2 CFPLIST(OPHEAD,NPARMS) IF M=1 THEN START XNAME<-STRING(DICTBASE+WORD(KK)) IF EXTRN=1 THEN XNAME<-"S#".XNAME CXREF(XNAME,PARMDYNAMIC!(EXTRN//3),2,JJ); ! %STSTEM & %EXTERNAL =STATIC ! %DYNAMIC = DYNAMIC FINISH IF M=0 AND RLEVEL=0 THEN CODE DES(JJ) J=15-M; PTYPE=TYPEP KFORM=NPARMS SNDISP=JJ>>16 ACC=JJ&X'FFFF' STORE TAG(KK,OPHEAD) END ROUTINE CFPLIST(INTEGERNAME OPHEAD,NPARMS) !*********************************************************************** !* COMPILE A FORMAL PARAMETER PART INTO A LIST OF PARAMETER TYPES * !* P(FPP)='('{(HOLE)(FPDEL)(NAMELIST)(MARK)}*')',0. * !* * !* THE LIST OF PARAMETER LOOKS LIKE:- * !* S1 = PTYPE FOR PARAM<<16! DIMENSION (DIMEN DEDUCED LATER) * !* S2 = ACC <<16 ! SPARE * !* S3 = 0 (RESERVED FOR FPP OF RTS) * !* * !* ON ENTRY P IS AT ALT OF FPP (WHICH MAY BE NULL) * !*********************************************************************** INTEGER OPBOT, PP OPHEAD=0; OPBOT=0 NPARMS=0; ! ZERO PARAMETERS AS YET WHILE A(P)=1 CYCLE; ! WHILE SOME(MORE) FPS PP=P+1+FROMAR2(P+1); ! TO NEXT FPDEL P=P+3; ! TO ALT OF FPDEL CFPDEL; ! GET TYPE & ACC FOR NEXT GROUP UNTIL A(P-1)=2 CYCLE; ! DOWN <NAMELIST> FOR EACH DEL BINSERT(OPHEAD,OPBOT,PTYPE<<16,ACC<<16,0) NPARMS=NPARMS+1 P=P+3 REPEAT P=PP REPEAT P=P+1 END ROUTINE CFPDEL !*********************************************************************** !* SET UP PTYPE & ACC FOR A FORMAL PARAMETER DEFINITION * !* P<FPDEL>=<TYPE><%QNAME'>, * !* '%RECORD'<%ARRAY'>'%NAME'. * !* (RT)(%NAME')(NAMELIST)(FPP), * !* '%NAME'. * !*********************************************************************** SWITCH FP(1:4) INTEGER FPALT FPALT=A(P); P=P+1 KFORM=0; LITL=0 ->FP(FPALT) FP(1): ! (TYPE)(%QNAME') ROUT=0; CLT CQN(P) FAULT(70,0) IF TYPE=5 AND ACC=0 P=P+1 ->PK FP(2): ! RECORD(%ARRAY')%NAME ARR=2-A(P); ROUT=0 ACC=8+8*ARR; TYPE=3; PREC=3 NAM=1; P=P+1; ->PK FP(3): ! (RT)(%NAME')(NAMELIST)(FPP) ROUT=1; NAM=1 ARR=0 IF A(P)=1 THEN START; ! RT=%ROUITNE TYPE=0; PREC=0 P=P+2 FINISH ELSE START P=P+1; CLT; ! RT=(TYPE)(FM) NAM=1 IF A(P)=2 THEN NAM=3; ! 1 FOR FN 3 FOR MAP P=P+2; ! PAST (%NAME') WHICH IS IGNORED FINISH ACC=16 ->PK FP(4): ! %NAME ACC=8; NAM=1 ROUT=0; TYPE=0 ARR=0; PREC=0 PK: PACK(PTYPE) END ROUTINE DIAG POINTER(INTEGER LEVEL) IF PARMTRACE#0 THEN START PUSH(RAL(LEVEL),1,CA,LDB<<24!3<<23) PF1(LDB,0,0,0) GRUSE(DR)=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) * !*********************************************************************** INTEGER W1, W3, INSRN, AT PUSH(LEVELINF, 0, NMAX<<16!N, 0) LEVEL=LEVEL+1 NMDECS(LEVEL)=0; AUXSBASE(LEVEL)=0 NAMES(LEVEL)=-1 ONINF(LEVEL)=0; ONWORD(LEVEL)=0 IF KK>=0 THEN START RLEVEL=RLEVEL+1; RBASE=RLEVEL FINISH FAULT(34, 0) IF LEVEL=MAX LEVELS FAULT(105, 0) IF LEVEL>MAX LEVELS IF KK>=0 AND RLEVEL>1 START; ! ROUTINE ENTRY COPY TAG(KK); JJ=K; ! LIST OF JUMPS J=MIDCELL IF J=0 AND LEVEL>2 START; ! REPLACE 'NOT USED' BIT REPLACE1(TAGS(KK), FROM1(TAGS(KK))&X'FFFF3FFF') FINISH ! ! NOW FILL ANY JUMPS TO THIS ROUTINE PLANTED SINCE ! THE ROUTINESPEC WAS COMPILED. SEE ALSO 'RT JUMP' ! WHILE J#0 CYCLE POP(J, INSRN, AT, W1) W3=CA-AT W3=W3//2 IF INSRN>>25=CALL>>1 INSRN=INSRN+W3 PLUG(1, AT, INSRN,4) REPEAT REPLACE2(TAGS(KK), CA); ! NOTE ADDR FOR FUTURE CALLS FINISH IF KK>=0 AND RLEVEL=1 THEN DIAG POINTER(LEVEL) C AND PSF1(STD,1,12) IF KK<0 THEN W3=0 ELSE W3=WORD(KK) L(LEVEL)=LINE; M(LEVEL)=W3 FLAG(LEVEL)=PTYPE; ! CURRENT BLOCK TYPE MARKER END 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 GRUSE(XNB)=0 GRUSE(CTB)=0; GRUSE(BREG)=0 IF LEVEL#2 THEN START ! PF1(LXN,0,TOS,0) GRUSE(XNB)=4; GRINF1(XNB)=RLEVEL-1; GRAT(XNB)=CA PF1(LD,0,XNB,12); ! COPY PLT DESCRIPTOR DIAG POINTER(LEVEL) PSF1(STD,1,12) W1=RLEVEL-1; W2=DISPLAY(W1) IF W1=1 THEN PF1(STXN,0,TOS,0) 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 PF1(ST,0,TOS,0); ! ST TOS PF1(STLN,0,TOS,0) 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 PARMTRACE#0 START PF1(LSS,0,PC,4*CONST BTM!X'80000000') IF PARMOPT#0; ! M'IDIA' IF KK>=0 OR LEVEL=2 START IF PARMOPT#0 THEN START PSF1(SLSS,0,LINE) N=N+4 FINISH ELSE PSF1(LSS,0,LINE) PF1(ST,0,TOS,0) FINISH ELSE START IF PARMOPT#0 THEN START PSF1(ST,1,N) N=N+4 FINISH PSF1(LSS,0,LINE) PSF1(ST,1,N) PSF1(LD,1,12); ! UPDATE BND FIELD DIAG POINTER(LEVEL) PSF1(STD,1,12) FINISH DIAGINF(LEVEL)=N N=N+4 GRUSE(ACCR)=0; ! NEEDED FOR %BEGIN BLOCKS FINISH IF PARMOPT#0 AND KK>=0 AND LEVEL=2 START PF1(STSF,0,BREG,0) PF1(STLN,0,TOS,0) PF1(SBB,0,TOS,0) PSF1(CPB,0,N) PPJ(7,13) FINISH ! ! CLAIM (THE REST OF) THE STACK FRAME ! IF KK>=0 OR LEVEL=2 START SET(RLEVEL)=N<<18!CA NMAX=N PF1(ASF+12*PARMCHK,0,0,0); ! ASF OR LB PPJ(0,4) IF PARMCHK#0 FINISH ! IF KK>=0 AND PARMCHK#0 START CHECK STOF; ! CHECK FOR STACK O'FLOW FINISH IF PARMDBUG#0 THEN SET LINE; ! TO CALL DBUG PACKAGE END ROUTINE CHECK STOF !*********************************************************************** !* CHECK THE STACK FOR OVERFLOW (LEAVING 4K MARGIN FOR MDIAG * !*********************************************************************** IF 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 ! PF1(STSF,0,TOS,0) PF1(LSS,0,TOS,0) PSF1(USH,0,14) PSF1(USH,0,-15) PF1(ICP,0,0,ST LIMIT>>1) PPJ(2,8) FINISH END; ! OF ROUTINE RHEAD ROUTINE CIOCP(INTEGER N,REG) !*********************************************************************** !* COMPILES A CALL ON IOCP ENTRY POINT NO 'N' * !* 2ND PARAMETER IS ALREAD IN THE ACC WHICH IS 32 BITS * !*********************************************************************** INTEGER XYNB,OP1,OP2 IF IOCPDISP=0 THEN CXREF(IOCPEP,PARMDYNAMIC,2,IOCPDISP) IF REGISTER(BREG)#0 THEN BOOT OUT(BREG) IF REG=ACCR THEN OP1=LUH AND OP2=ST C ELSE OP1=LDTB AND OP2=STD PSF1(OP1,0,N) PSF1(PRCL,0,4) PF1(OP2,0,TOS,0) XYNB=SET XORYNB(-1,-1); ! TO PLT PSF1(RALN,0,7) PF1(CALL,2,XYNB,IOCPDISP) FORGET(-1) END ROUTINE CUI(INTEGER CODE) !*********************************************************************** !* COMPILE AN UNCONDITIONAL INSTRN WHEREEVER IT OCCURS * !* CODE=0 UNCONDITIOALLY,=1 AFTER %THEN, =2 AFTER %ELSE * !*********************************************************************** INTEGER MARKER,J,LNAME,TYPEP,PRECP,GWRDD,LWB,XYNB,ARRP,ALT SWITCH SW(1:9) REPORTUI=0 ALT=A(P) ->SW(ALT) SW(1): ! (NAME)(APP)(ASSMNT?) P=P+1; MARKER=P+FROMAR2(P) IF A(MARKER)=1 THEN START J=P+2; P=MARKER+2 ASSIGN(A(MARKER+1),J) FINISH ELSE START P=P+2 CNAME(0,0) P=P+1 FINISH AUI: J=A(P); P=P+1 IF J=1 THEN CUI(CODE) RETURN SW(2): ! -> (NAME)(APP) NMDECS(LEVEL)=NMDECS(LEVEL)!1 CURR INST=1 IF CODE=0 LNAME=FROM AR2(P+1) J=A(P+3); P=P+4 IF J=2 THEN START; ! SIMPLE LABEL ENTER JUMP(15,LNAME,0) REPORTUI=1 FINISH ELSE START; ! SWITCH LABELS COPY TAG(LNAME) ARRP=ARR GWRDD=SNDISP<<2; ! BYTE DISP OF DESCRIPTOR IN PLT UNLESS OLDI=LEVEL AND TYPE=6 START FAULT(4,LNAME); P=P-1; SKIP APP RETURN FINISH LWB=FROM2(K); ! GET LOWER BOUND CSEXP(BREG,X'51') IF ARRP=1 THEN PSF1(SBB,0,LWB) XYNB=SET XORYNB(-1,-1); ! TO PLT PF1(JUNC,3,XYNB,GWRDD); ! JUMP INDIRECT VIA WORD ARRAY ! OF 32 BIT RELOCATED ADDRESSES REPORTUI=1; FORGET(-1) FINISH RETURN SW(3): ! RETURN FAULT(30,0) UNLESS FLAG(LEVEL)&X'3FFF'=X'1000' P=P+1 RET: RT EXIT REPORT UI=1 CURR INST=1 IF CODE=0 RETURN SW(4): ! %RESULT(ASSOP)(EXPR) PTYPE=FLAG(LEVEL)&X'3FFF'; UNPACK IF PTYPE>X'1000' AND A(P+1)#3 THEN START; ! ASSOP #'->' IF A(P+1)=1 AND NAM#0 AND A(P+5)=4 AND A(P+6)=1 START P=P+7; TYPEP=TYPE; PRECP=PREC CNAME(4,ACCR) FAULT(81,0) UNLESS A(P)=2; P=P+1 FAULT(83,0) UNLESS TYPEP=TYPE AND PRECP=PREC ->RET FINISH IF A(P+1)=2 THEN START; ! ASSOP='=' P=P+2 IF NAM#0 THEN TYPE=1; ! MAPS HAVE INTEGER RESULTS IF TYPE=5 THEN START CSTREXP(0,ACCR) PSF1(LD,1,DISPLAY(RBASE)-8); ! RESULT DESCRPT PF1(IAD,0,PC,SPECIAL CONSTS(2)) PF2(MV,1,1,0,0,UNASSPAT&255) PSF1(LDB,2,DISPLAY(RBASE)-8) COPY DR FINISH ELSE START IF PREC<5 THEN PREC=5 IF NAM=0 THEN KK=PREC<<4!TYPE ELSE KK=X'51' CSEXP(ACCR,KK) FINISH; ->RET FINISH FINISH FAULT(31,0) P=P+2; SKIP EXP; ! IGNORE SPURIOUS RESULT RETURN SW(5): ! %MONITOR (AUI) PSF1(LSD,0,0); ! ERR=0 & EXTRA =0 PPJ(0,2); ! TO ERROR ROUTINE P=P+1; ->AUI SW(6): ! %STOP PPJ(0,21) P=P+1 CURR INST=1 IF CODE=0 REPORTUI=1 RETURN SW(7): !'%SIGNAL'(EVENT')(N)(OPEXPR) PSF1(PRCL,0,4) PSF1(JLK,0,1); ! STACK DUMMY PC IF NMDECS(LEVEL)&16 #0 START; ! IN AN 'ON' GROUP IF FLAG(LEVEL)<=2 START; ! IN A BEGIN BLOCK PSF1(LD,1,12); ! SO RESET DIAG POINTER DIAGPOINTER(LEVEL-1); ! TO NEXT OUTER BLOCK PSF1(STD,1,12) PF1(STLN,0,TOS,0) FINISH ELSE START; ! 'ON IN A RT/FN/MAP PSF1(LSS,1,0); ! GET PREVIOUS LNB PF1(ST,0,TOS,0); ! AND STACK THAT FINISH FINISH ELSE PF1(STLN,0,TOS,0) GRUSE(ACCR)=0 J=A(P+2); ! EVENT NO FAULT2(26,J,0) UNLESS 1<=J<=15 IF A(P+3)=1 START; ! SUBEVENT SPECIFIED P=P+4; CSEXP(ACCR,X'51') PF1(AND,0,0,255) PF1(OR,0,0,256*J) FINISH ELSE PF1(LSS,0,0,256*J) PSF1(SLSS,0,0) PF1(ST,0,TOS,0) XYNB=SET XORYNB(-1,-1); ! TO PLT PSF1(RALN,0,9) PF1(CALL,2,XYNB,40) CURR INST=1 IF CODE=0 REPORTUI=1; RETURN SW(8): ! %EXIT SW(9): ! %CONTINUE ALT=ALT&7; ! 0 FOR EXIT 1 FOR CONTINUE IF EXITLAB=0 THEN FAULT2(54+ALT,0,0) AND RETURN KK=INTEGER(ADDR(EXITLAB)+4*ALT) ENTER JUMP(15,KK,B'10') REPORTUI=1 CURR INST=1 IF CODE=0 END ROUTINE CIFTHEN(INTEGER MARKIU,MARKC,MARKUI,MARKE,MARKR,SKIP) !*********************************************************************** !* THIS ROUTINE COMPILES CONDITIONAL EXPRESSIONS.IT REQUIRES THE * !* FOLLOWING PARAMETERS TO BE SET TO THEIR A .R. ENTRY. * !* MARKIU TO THE ENTRY FOR P(%IU) * !* MARKC TO THE ENTRY FOR P(COND) * !* MARKUI TO THE ENTRY FOR (FIRST OCCURRENCE OF) P(UI) * !* MARKE TO THE ENTRY FOR P(ELSE') - =0 FOR BACKWARDS CONDITION * !* MARKR TO ENTRY FOR P(RESTOFIU) - =0 FOR BACKWARDS CONDITION * !*********************************************************************** INTEGER ALTUI,CCRES,ELRES,THENLAB,ELSELAB,USERLAB,REPORT,START, C ELSEALT,K CONSTINTEGER NULL ELSE=4 SWITCH ESW(1:NULL ELSE) SET LINE UNLESS SKIP=YES MARKIU=A(MARKIU); ! ALT OF IU 1=%IF,2=%UNLESS PLABEL=PLABEL-1 THENLAB=PLABEL START=0; ! NO START IN CONDITION YET ELSELAB=0; ! MEANS NO ELSE CLAUSE P=MARKC IF MARKR>0 AND A(MARKR)<=2 THEN START=1; ! '%START' OR '%THENSTART' IF MARKE#0 AND LEVEL<2 AND START=0 THEN FAULT(57,0) USERLAB=-1 IF START#0 THEN ALTUI=0 ELSE ALTUI=A(MARKUI) IF ALTUI=2 AND A(MARKUI+3)=2 THEN C USERLAB=FROM AR2(MARKUI+1); ! UI = SIMPLE LABEL IF 8<=ALTUI<=9 AND EXITLAB#0 START; ! VALID EXIT IF ALTUI=8 THEN USERLAB=EXITLAB ELSE USERLAB=CONTLAB FINISH ! IF SKIP=YES THEN START; ! NO CODE NEEDED IF START#0 START P=MARKR+1 CSTART(2,1); ! NO CODE MARKE=P FINISH CCRES=1; ! NO CODE FOR ELSE ->ELSE FINISH ! IF USERLAB>=0 THEN START; ! FIRST UI IS'->'<LABEL> NMDECS(LEVEL)=NMDECS(LEVEL)!1 CCRES=CCOND(0,3-MARKIU,USERLAB) IF CCRES#0 THEN CCRES=CCRES!!3; ! CONDITION BACKWARDS! THENLAB=0; ! NO THENLAB IN THIS CASE REPORT=1; ! UI TRANSFERED CONTROL FINISH ELSE START CCRES=CCOND(1,MARKIU,THENLAB) IF START#0 THEN START; ! %THEN %START IF CCRES=0 START; ! CONDITIONAL FAULT(57,0) IF LEVEL<2 NMDECS(LEVEL)=NMDECS(LEVEL)!1 FINISH P=MARKR+1 CSTART(CCRES,1) IF A(P)<=2 THEN PLABEL=PLABEL-1 AND ELSELAB=PLABEL MARKE=P REPORT=LAST INST FINISH ELSE START IF CCRES#2 START P=MARKUI; CUI(1) REPORT=REPORTUI FINISH ELSE START; ! FIRST UI NEVER EXECUTED REPORT=1 FINISH FINISH FINISH ELSE: ! ELSE PART IF MARKE=0 THEN ELSEALT=NULL ELSE ELSE ELSEALT=A(MARKE) IF ELSEALT<NULL ELSE THEN PLABEL=PLABEL-1 AND ELSELAB=PLABEL P=MARKE+1 IF REPORT=0=CCRES AND ELSEALT<NULL ELSE THEN REPORT=1 AND C ENTER JUMP(15,ELSELAB,B'10');! LONG JUMP BUT SAVE ENV IF THENLAB>0 THEN ELRES=ENTER LAB(THENLAB,B'11'!REPORT<<2) ! CONDITIONAL&MERGE OR REPLACE ->ESW(ELSEALT) ESW(1): ! '%ELSESTART' IF CCRES=0 THEN NMDECS(LEVEL)=NMDECS(LEVEL)!1 CSTART(CCRES,2) REPORT=LAST INST ->ENTER ELSELAB ESW(2): ! '%ELSE' (%IU) ETC MARKE=0; MARKUI=0 MARKR=P+1+FROMAR2(P+1) IF A(MARKR)=3 THEN START MARKE=MARKR+1+FROM AR2(MARKR+1) MARKUI=MARKR+3 FINISH IF CCRES=1 OR SKIP=YES THEN K=YES ELSE K=NO CIFTHEN(P,P+3,MARKUI,MARKE,MARKR,K) ->ENTER ELSELAB ESW(3): ! '%ELSE'<UI> IF CCRES#1 THEN START IF START#0 THEN SET LINE; ! FOR CORRECT LINE IF FAILS IN UI IF THENLAB=0 THEN K=0 ELSE K=2 CUI(K) REPORT=REPORTUI FINISH ENTER ELSELAB: IF ELSELAB>0 THEN ELRES=ENTER LAB(ELSELAB,B'11'!REPORT<<2) ! CONDITIONAL MERGE ESW(NULL ELSE): ! NULL ELSE CLAUSE END ROUTINE CSTART(INTEGER CCRES,CODE) !*********************************************************************** !* COMPILE A COMPLETE START-FINISH BLOCK BY RECURSION * !* IF START NEVER EXECUTED SKIP TO CORRESPONDING FINISH * !* CODE=0 WAS UNCONDITIONAL NOW SHOULD BE UNUSED * !* CODE=1 AFTER THEN * !* CODE=2 AFTER ELSE * !* CODE=3 AFTER ONEVENT * !* P ON ENTRY TO FORWARD POINTER TO THE RIGHT FINISH * !* P ON EXIT TO THE ELSE CLAUSE AFTER THE RIGHT FINISH * !*********************************************************************** INTEGER SKIPCODE,FINISHAR,OLDNEXTP,OLDLINE SKIPCODE=NO IF 1<=CODE<=2 AND CCRES!CODE=3 THEN SKIPCODE=YES; ! NEVER EXECUTED FINISHAR=FROMAR4(P); ! TO START OF AR FOR FINISH IF FINISHAR<=P THEN ABORT; ! FOR TESTING OLDLINE=LINE; ! FOR ERROR MESSAGES CYCLE; ! THROUGH INTERVENING STATMNTS OLDNEXTP=NEXTP IF SKIP CODE=NO THEN COMPILE A STMNT ELSE START LINE=A(NEXTP+3)<<8!A(NEXTP+4) NEXTP=NEXTP+A(NEXTP)<<16+A(NEXTP+1)<<8+A(NEXTP+2) FINISH REPEAT UNTIL OLDNEXTP>=FINISHAR; ! HAVING COMPILED FINISH P=FINISHAR+6; ! TO ELSE CLAUSE ! IF A(P)<=2 AND CODE#1 THEN FAULT2(45+CODE,OLDLINE,0) IF SKIPCODE=YES THEN LAST INST=1 END ROUTINE CCYCBODY(INTEGER UA,ELAB,CLAB) !*********************************************************************** !* COMPILES A CYCLE REPEAT BODY BY RECURSION * !* ON ENTRY P IS TO FORWARD POINTER. ON EXIT TO ALT OF UNTIL * !* UA = O IF UNTIL NOT ALLOWED * !* ELAB&CLAB ARE LABELS FOR ELSE & CONTINUE * !*********************************************************************** INTEGER FINISHAR,OLDLINE,SAVEE,SAVEC FINISHAR=FROMAR4(P) IF FINISHAR<=P THEN ABORT OLDLINE=LINE; SAVEE=EXIT LAB; SAVEC=CONTLAB EXITLAB=ELAB; CONTLAB=CLAB WHILE NEXTP<=FINISHAR CYCLE COMPILE A STMNT REPEAT EXIT LAB=SAVEE; CONTLAB=SAVEC P=FINISHAR+6 IF A(P)=1 AND UA=0 THEN FAULT2(12,OLDLINE,0) END ROUTINE CLOOP(INTEGER ALT, MARKC, MARKUI) !*********************************************************************** !* ALT=1 FOR %WHILE, =2 FOR %UNTIL, =3 FOR %FOR * !* MARKC IS TO THE CONDITION OR CONTROL CLAUSE * !* MARKUI IS TO THE UI, SPECIAL FOR %CYCLE * !*********************************************************************** INTEGER L1,L2,L3,CCRES,ELRES INTEGER FORNAME,INITTYPE,INITVAL,STEPTYPE,STEPVAL,FINALTYPE,FINALVAL,C FACC,FDISP,FBASE,INITP,REPMASK,USEDEBJ,DEBTO ROUTINESPEC FOREXP(INTEGERNAME ETYPE,EVALUE,INTEGER TT,REG) ROUTINESPEC VALIDATE FOR SWITCH SW(0:6) P=MARKC SFLABEL=SFLABEL-2 L1=SFLABEL; L2=L1+1 ! ! SET L3 FOR ALTS 0,5&6 ONLY ! L3=0 IF B'1100001'&1<<ALT#0 THEN L3=SFLABEL-1 AND SFLABEL=L3 ! ! UPDATE THE LINE NUMBER FOR ALTS 1 TO 3 ONLY ! IF 1<=ALT<=3 THEN SET LINE ! ! ENTER THE FIRST LABEL(L1) FOR ALL ALTS EXCEPT 3 & 6 ! IF B'0110111'&1<<ALT#0 THEN ELRES=ENTER LAB(L1,0) ->SW(ALT) SW(0): ! %CYCLE C CYC BODY(1,L2,L3) ELRES=ENTER LAB(L3,B'011') IF A(P)=1 START; ! %REPEAT %UNTIL <COND> P=P+1; CCRES=CCOND(0,1,L1) FINISH ELSE ENTER JUMP(15,L1,0) ELRES=ENTER LAB(L2,B'011') WAYOUT: ! REMOVE LABELS NOT REQUIRED REMOVE LAB(L1) REMOVE LAB(L2) REMOVE LAB(L3) IF L3>0 RETURN SW(1): ! UI WHILE COND CCRES=CCOND(0,1,L2) P=MARKUI CUI(1) ENTERJUMP(15,L1,0); ! UNCONDITIONALLY BACK TO WHILE ELRES =ENTER LAB(L2,B'111'); ! CONDITIONAL(?) & REPLACE ENV ->WAYOUT SW(2): ! UI %UNTIL COND P=MARKUI CUI(1) P=MARKC CCRES=CCOND(0,1,L1) ->WAYOUT SW(3): ! UI %FOR .... SW(6): ! %FOR ... %CYCLE FORNAME=FROMAR2(P) INITP=P+2; P=INITP COPY TAG(FORNAME) FDISP=K; FBASE=I; FACC=2*NAM FAULT2(91,0,FORNAME) UNLESS TYPE=1 AND PREC=5 AND ROUT=0=ARR WARN(4,FORNAME) UNLESS FBASE=RBASE ! SKIP EXP; ! P TO STEP EXPRSN FOR EXP(STEPTYPE,STEPVAL,1,ACCR); ! STEP TO ACCR AND TEMP IF STEPTYPE=0 START FAULT2(92,0,0) IF STEPVAL=0; ! ZERO STEP FINISH ELSE START IF PARMOPT#0 THEN PPJ(26,11); ! FAULT COMPUTED ZERO STEP FINISH ! FOR EXP(FINALTYPE,FINALVAL,1,ACCR);! EVALUATE FINAL ! P=INITP FOR EXP(INITTYPE,INITVAL,0,BREG);! INITIAL VALUE TO B IF PARMOPT#0 THEN VALIDATE FOR ! USEDEBJ=0; ! DONT USE IT IF STEPVAL=-1 AND FINALTYPE!STEPTYPE=0 AND FINALVAL=1 START USEDEBJ=1; ! CAN USE BEST BRANCH INSTRN PSF1(LB,0,INITVAL) IF INITTYPE=0 UNLESS INITTYPE=0 AND INITVAL>=1 THEN C ENTERJUMP(32+13,L2,B'10'); ! JAF B>0 NO TRAVERSES DEBTO=CA; ! SAVE CA FOR DEBJ FINISH ELSE START IF INITTYPE!STEPTYPE=0 THEN START PSF1(LB,0,INITVAL-STEPVAL) FINISH ELSE START PSF1(LB,0,INITVAL) IF INITTYPE=0 PSF1(SBB,STEPTYPE,STEPVAL) FINISH ! ! HAVE B SET TO INIT-STEP. FOR COMPUTED STEPS NOW MUST CHECK ! FOR NEGATIVE TRAVERSES. FOR FIXED STEPS THIS CAN BE SET ! IN MASK FOR REPEATING ! IF STEPTYPE=1 THEN START PF1(LSS,0,BREG,0) PSF1(IRSB,FINALTYPE,FINALVAL) PSF1(IDV,1,STEPVAL) GRUSE(ACCR)=0 ENTERJUMP(37,L2,B'10') REPMASK=7 FINISH ELSE REPMASK=8!(2<<(STEPVAL>>31)); ! A OR C ! ELRES=ENTER LAB(L1,0); ! LABEL FOR REPEATING ! IF STEPTYPE=0 AND STEPVAL=1 START PSF1(CPIB,FINALTYPE,FINALVAL) FINISH ELSE START PSF1(CPB,FINALTYPE,FINALVAL) PSF1(ADB,STEPTYPE,STEPVAL) FINISH GRUSE(BREG)=0 ENTER JUMP(REPMASK,L2,B'10') FINISH BASE=FBASE; AREA=-1 PSORLF1(STB,FACC,AREA CODE,FDISP) NOTE ASSMENT(BREG,2,FORNAME) ! P=MARKUI; ! TO UI OR '%CYCLE'(HOLE) IF ALT=3 THEN START; ! DEAL WITH CONTROLLED STMNTS CUI(0) FINISH ELSE START CCYCBODY(0,L2,L3) ELRES=ENTER LAB(L3,B'011'); ! LABEL FOR CONTINUE FINISH BASE=FBASE; ACCESS=FACC AREA=-1; DISP=FDISP NAMEOP(2,BREG,4,FORNAME); ! CONTROL TO B IF USEDEBJ=0 THEN ENTER JUMP(15,L1,0) ELSE C PSF1(DEBJ,0,(DEBTO-CA)//2) AND GRUSE(BREG)=0 ELRES=ENTERLAB(L2,B'111'!!(USEDEBJ<<2));! REPLACE ENV UNLESS DEBJ ! WHEN MERGE ENV ->WAYOUT SW(4): ! %WHILE COND %CYCLE CCRES = CCOND(0,1,L2) C CYC BODY(0,L2,L1) ENTER JUMP(15,L1,0) ELRES = ENTER LAB(L2,B'111'); ! CONDITIONAL & REPLACE ENV ->WAYOUT SW(5): ! %UNTIL ... %CYCLE ! ALSO %CYCLE... %REPEAT %UNTIL ! MARKUI TO %CYCLE P=MARKUI C CYC BODY(0,L2,L3) P=MARKC; ELRES=ENTER LAB(L3,B'011');! CONTINUE LABEL IF NEEDED CCRES=CCOND(0,1,L1) ELRES=ENTER LAB(L2,B'011') ->WAYOUT ROUTINE FOREXP(INTEGERNAME ETYPE,EVALUE,INTEGER TOTEMP,USEREG) !*********************************************************************** !* P INDEXES EXPRESSION. IF CONST PUT INTO EVALUE OTHERWISE * !* COMPILE TO USEREG AND STORE IN TEMP IF TOTEMP#0 * !*********************************************************************** INTEGER INP,VAL,OP INP=P; P=P+3 IF INTEXP(VAL)=0 AND IMOD(VAL)<X'1FFFF' START EVALUE=VAL; ETYPE=0; ! EXPRESSION A LITERAL CONST RETURN FINISH P=INP CSEXP(USEREG,X'51'); ! INTEGER MODE TO REG ETYPE=1; ! NOT CONST IF TOTEMP#0 START GET WSP(VAL,1) IF USEREG=ACCR THEN OP=ST ELSE OP=STB PSF1(OP,1,VAL) EVALUE=VAL FINISH END ROUTINE VALIDATE FOR !*********************************************************************** !* INITIAL VALUE IN BREG OR A CONSTANT * !*********************************************************************** INTEGER I IF INITTYPE!STEPTYPE!FINALTYPE=0 START J=FINALVAL-INITVAL; ! ALL CONSTANT CAN CHECK NOW IF (J//STEPVAL)*STEPVAL#J THEN FAULT2(93,0,0) RETURN FINISH IF STEPTYPE=0 AND IMOD(STEPVAL)=1 THEN RETURN ! ! CHECK BY PLANTING CODE ! IF INITTYPE=0 THEN PSF1(LSS,0,INITVAL) ELSE PF1(LSS,0,BREG,0) PSF1(IRSB,FINALTYPE,FINALVAL) PSF1(IMDV,STEPTYPE,STEPVAL) PF1(LSS,0,TOS,0) GRUSE(ACCR)=0 PPJ(36,11) END END ROUTINE ASSIGN(INTEGER ASSOP,P1) !*********************************************************************** !* HANDLES ARITHMETIC,STRING & ADDRESS ASSIGNMENTS TO VARIABLES * !* FORMAL PARAMETERS AND DOPEVECTORS * !* ASSOP:- * !* 1 IS FOR '==' * !* 2 IS FOR '=' * !* 3 IS FOR '<-' (JAM TRANSFER) * !* 4 IS FOR '->' (UNCONDITIONAL RESOLUTION) * !* >4 IS FOR STORE ACC BY 'ASSOP&3' INTO NAME * !* * !* P POINTS TO THE EXPRESSION. P1 TO THE NAME ON LHS * !*********************************************************************** INTEGER Q,QQ,KK,TYPEP,PRECP,PTYPEP,JJJ,P2,JJ,REG,STCODE, C RHTYPE,ACCP,II,HEAD1,NOPS,TPCELL,LVL,BOT1,LHNAME,RHNAME RECORD R(RD) SWITCH SW(0:3); ! TO SWITCH ON ASSOP P2=P IF ASSOP>4 THEN RHTYPE=TYPE LHNAME=A(P1)<<8!A(P1+1) P=P1; REDUCE TAG; ! LOOK AT LH SIDE PTYPEP=PTYPE; JJ=J KK=K; II=I; LVL=OLDI TPCELL=TCELL; ACCP=ACC P=P2; TYPEP=TYPE; PRECP=PREC; ! SAVE USEFUL INFO FOR LATER -> SW(ASSOP&3) ! SW(2):SW(3): ! ARITHMETIC ASSIGNMENTS IF TYPE=3 THEN ->RECOP TYPE=1 UNLESS TYPE=2 OR TYPE=5; ! IN CASE OF RUBBISHY SUBNAMES ->ST IF TYPE=5; ! LHS IS A STRING BACK: HEAD1=0; ! CLEAR TEMPORAYRY LIST HEADS TYPE=1 UNLESS TYPE=2; ! DEAL WITH UNSET NAMES TYPEP=TYPE NOPS=1<<18+1; P=P2+3 PUSH(HEAD1,ASSOP&3+33,PRECP,0); ! ASSIGNMENT OPERATOR BOT1=HEAD1 PUSH(HEAD1,PTYPEP<<16!2,P1,0); ! LHS IF ASSOP>4 THEN START FAULT(24,0) UNLESS TYPE=RHTYPE PUSH(HEAD1,RHTYPE<<16!9,0,0) OLINK(ACCR)=HEAD1 FINISH ELSE TORP(HEAD1,BOT1,NOPS); ! RHS TO REVERSE POLISH EXPOP(HEAD1,-1,NOPS,256+PRECP<<4+TYPEP); ! PLANT CODE ! CLEAR LIST(HEAD1) ASLIST(BOT1)_LINK=ASL ASL=HEAD1 RETURN !NA: NOTE ASSMENT(-1,ASSOP&3,A(P1)) ST: ! STRINGS ! ! PICK OFF NULL STRINGS AND SUBSTITUTE A CRAFTY MVL FOR S="" ! IF A(P+3)=4 AND A(P+4)=2 AND C A(P+5)=X'35' AND A(P+10)=0 AND A(P+11)=2 THEN START Q=P+12-A(P+10)>>1 P=P1; CNAME(1,DR) PF2(MVL,0,1,0,0,0) P=Q; RETURN FINISH IF ASSOP<=3 THEN CSTREXP(0,ACCR) ASSOP=ASSOP&3 QQ=STRINGL; Q=P REGISTER(ACCR)=1 OLINK(ACCR)=ADDR(R) R_PTYPE=X'51'; R_FLAG=9; R_UPTYPE=0 R_XB=ACCR P=P1; CNAME(1,DR) IF R_FLAG#9 THEN PF1(LSD,0,TOS,0) PF1(IAD,0,PC,SPECIAL CONSTS(2)) IF ASSOP#3 AND (ROUT#0 OR NAM#0=ARR) AND QQ=0 START ! LHS=MAP : DR BOUND NOT VALID ! ALSO NAMES MAPPED ==STRING(ADDR) IF PARMOPT#0 THEN PPJ(0,18) ELSE START PF1(STUH,0,BREG,0) PF1(LUH,0,BREG,0) PF1(LDB,0,BREG,0) FINISH GRUSE(BREG)=0 FINISH GRUSE(ACCR)=0 REGISTER(ACCR)=0 IF QQ>0 AND ASSOP#3 THEN PF2(MV,0,0,QQ,0,0) ELSESTART IF ASSOP=3 THEN PF1(STD,0,TOS,0) PF2(MV,1,1,0,0,UNASSPAT&255) IF PARMARR#0 OR ASSOP=3 THEN PSF1(USH,0,8) ANDC PSF1(USH,0,-40) IF PARMARR#0 AND ASSOP=2 THEN PPJ(36,9) IF ASSOP=3 THEN START PF1(IRSB,2,TOS,0) PF1(ST,2,7,0); ! STORE AMENDED CURRENT LENGTH FINISH FINISH P=Q; RETURN ! ! THIS SECTION DEALS WITH OPERATIONS ON COMPLETE RECORDS ! RECOP: ! LHS IS RECORD WITHOUT SUBNAME REG=ACCR; ! IN CASE FAULT 66 Q=TSEXP(JJJ) IF Q=1 AND JJJ=0 START; ! CLEAR A RECORD TO ZERO P=P1; CNAME(3,DR) IF ACC<=128 THEN JJ=0 AND KK=ACC-1 ELSE START JJ=1; KK=0 IF NAM#0 OR ARR#0 THEN PSF1(LDB,0,ACC) FINISH PF2(MVL,JJ,1,KK,0,0) FINISH ELSE START ->BACK UNLESS TYPE=3 AND A(P2+3)=4 AND A(P2+4)=1 P=P2+5; CNAME(3,ACCR) ACCP=ACC UNLESS A(P)=2 THEN FAULT2(66,0,LHNAME) AND ->F00 R_PTYPE=X'61'; R_FLAG=9 R_XB=ACCR<<5; R_D=0 OLINK(ACCR)=ADDR(R) REGISTER(ACCR)=1 P=P1; CNAME(3,DR) REGISTER(ACCR)=0 IF R_FLAG#9 THEN PF1(LSD,0,TOS,0) IF ASSOP=2 AND ACCP#ACC THEN C FAULT2(67,LHNAME,FROMAR2(P2+5)) AND ->F00 IF ACCP>ACC THEN ACCP=ACC UNTIL ACCP=0 CYCLE IF ACCP>128 THEN KK=128 ELSE KK=ACCP PF2(MV,0,0,KK-1,0,0) ACCP=ACCP-KK REPEAT GRUSE(ACCR)=0 FINISH P=P2; SKIP EXP GRUSE(DR)=0 RETURN SW(0): ! RESOLUTION P=P1; CNAME(2,DR) P=P2; IF TYPE=5 THEN CRES(0) ELSE START SKIP EXP FAULT2(71,0,FROMAR2(P1)) UNLESS TYPE=7 FINISH RETURN SW(1): ! '==' AND %NAME PARAMETERS REG=ACCR; STCODE=ST; ! NORMALLY USE ACC ->F81 UNLESS A(P2+3)=4 AND A(P2+4)=1 FAULT2(82,0,LHNAME) AND ->F00 UNLESS NAM=1; ! ONLY POINTERS ON LHS OF== P=P2+5 RHNAME=A(P)<<8!A(P+1) ->ARRNAME IF ARR=1 IF A(P1+2)=2=A(P1+3) START; ! LHS SCALAR POINTERNAME COPYTAG(RHNAME) ; ! LOOK AT RHS IF PTYPE#SNPT AND ARR#0 THEN REG=DR AND STCODE=STD FINISH CNAME(3,REG); ! DESCRPTR TO ACC R_PTYPE=X'61'; R_FLAG=9 R_XB=REG OLINK(REG)=ADDR(R) REGISTER(REG)=1 ->F81 UNLESS A(P)=2; ! NO REST OF EXP ON RHS Q=P+1; P=P1 ->F83 UNLESS TYPE=TYPEP AND PREC=PRECP ->F86 UNLESS OLDI<=LVL OR BASE=0 OR NAM#0 ! GLOBAL == NONOWN LOCAL CNAME(6,0) IF R_FLAG#9 THEN START IF REG#ACCR THEN ABORT PF1(LSD,0,TOS,0) GRUSE(ACCR)=0 FINISH REGISTER(REG)=0 COM: PSORLF1(STCODE,ACCESS,AREA CODE,DISP) IF REG=DR AND ACCESS#0 THEN ABORT NOTE ASSMENT(REG,1,A(P1)<<8!A(P1+1)) P=Q; RETURN ARRNAME: CNAME(12,ACCR) IF ACCESS>=8 THEN ACCESS=ACCESS-4 ELSE ACCESS=0 ->F83 UNLESS TYPE=TYPEP AND PREC=PRECP C AND ARR>0 ->F86 UNLESS OLDI<=LVL OR BASE=0 OR NAM#0 ! GLOBAL == NONOWN LOCAL TYPE=0 NAMEOP(2,ACCR,16,-1) R_PTYPE=X'72'; R_UPTYPE=0 R_FLAG=9; R_XB=ACCR R_D=-1 REGISTER(ACCR)=1 OLINK(ACCR)=ADDR(R) ->F81 UNLESS A(P)=2 Q=P+1; P=P1 CNAME(6,0) PF1(LSQ,0,TOS,0) UNLESS R_FLAG=9 REGISTER(ACCR)=0 ->COM F83: FAULT2(83,LHNAME,RHNAME); ->F00 F86: FAULT2(86,LHNAME,RHNAME); ->F00 F81: FAULT2(81,0,LHNAME) F00: REGISTER(REG)=0 P=P2; SKIP EXP END ROUTINE CSEXP(INTEGER REG,MODE) !*********************************************************************** !* COMPILE A SIGNED EXPRESSION TO REGISTER 'REG' IN MODE 'MODE' * !* MODE=1 FOR %INTEGER, =2 REAL, =3 LONG,=0 INTEGER %IF POSSIBLE * !* MODE=5 FOR ADDRESS EXPRESSNS(IE LEAVE ANY CONSTANT IN 'ADISP')* !*********************************************************************** INTEGER EXPHEAD,NOPS,EXPBOT EXPHEAD=0; EXPBOT=0 NOPS=0 P=P+3 TORP(EXPHEAD,EXPBOT,NOPS) ! EXPOP(EXPHEAD,REG,NOPS,MODE) ! CLEAR LIST(EXPHEAD) ASLIST(EXPBOT)_LINK=ASL ASL=EXPHEAD END INTEGERFN CONSTEXP(INTEGER PRECTYPE) !*********************************************************************** !* COMPILES AN EXPRESSION WHICH SHOULD EVALUATE TO A CONSTANT OF * !* TYPE 'PRECTYPE'. P AS FOR FN INTEXP. * !*********************************************************************** INTEGER EXPHEAD,EXPBOT,NOPS,RES EXPHEAD=0; EXPBOT=0; NOPS=0; RES=0 TORP(EXPHEAD,EXPBOT,NOPS) ->WAYOUT UNLESS NOPS&X'00040000'=0 EXPOP(EXPHEAD,ACCR,NOPS,X'200'+PRECTYPE) IF EXPOPND_FLAG=3 THEN RES=EXPOPND_XTRA AND ->WAYOUT ->WAYOUT UNLESS EXPOPND_FLAG<=1 RES=ADDR(EXPOPND_D) WAYOUT: MONITOR IF RES=0 AND DCOMP#0 ASLIST(EXPBOT)_LINK=ASL ASL=EXPHEAD RESULT=RES END INTEGERFN INTEXP(INTEGERNAME VALUE) !*********************************************************************** !* COMPILES AN EXPRESSION WHICH SHOULD EVALUATE TO A CONSTANT * !* VALUE RETURNED IN VALUE. RESULT#0 IF FAILED TO EVALUATE * !* P POINTS TO P(+') IN (+')(OPERNAD)(RESTOFEXPR) * !*********************************************************************** INTEGER EXPHEAD,EXPBOT,NOPS,CODE,SPTYPE,SACC EXPHEAD=0; EXPBOT=0; NOPS=0; CODE=0 SPTYPE=PTYPE; SACC=ACC; ! CALLED IN DECLARATIONS TORP(EXPHEAD,EXPBOT,NOPS) IF NOPS&X'00040000'=0 AND TYPE=1 START EXPOP(EXPHEAD,ACCR,NOPS,X'251') CODE=1 UNLESS EXPOPND_FLAG<=1 AND EXPOPND_PTYPE=X'51' VALUE=EXPOPND_D FINISH ELSE CODE=1 AND VALUE=1 ASLIST(EXPBOT)_LINK=ASL ASL=EXPHEAD ACC=SACC; PTYPE=SPTYPE UNPACK RESULT=CODE END ROUTINE TORP(INTEGERNAME HEAD,BOT,NOPS) !*********************************************************************** !* 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. * !* N.B. AN INTEGER EXPRESSION IS A SPECIAL CASE OF A REAL EXPRSN * !* THE TOP 20 BITS OF NOPS ARE USED TO RETURN DETAILS OF THE EXPR * !* THESE BITS SIGNIFY AS FOLLOWS:- * !* 1<<17 CONTAINS VARIABLE OF MORE THAN 32 BITS * !* 1<<18 NOT CONSTANT EXPRSSN IE CONTAINS AT LEAST 1 VARIABLE * !* 1<<19 COMPLEX IE CONTAINS FN CALL OR NEEDS DR TO EVALUATE * !* 1<<20 CONTAINS THE OPERATOR + * !* 1<<21 CONTAINS THE - OPERATOR(INCLUDES UNARY MINUS) * !* 1<<22 CONTAINS OPERATOR !! (INCUDES UNARY NOT) * !* 1<<23-7 CONTAINS OPERATORS !,*,//,/,& RESPECTIVELY * !* 1<28&9 CONTAINS << OR >> * !* 1<<30 CONTAINS EXPONETIATION * !*********************************************************************** SWITCH OPERAND(1:3) CONSTBYTEINTEGERARRAY PRECEDENCE(1:15)=3,3,4,5,5,4,3,3,4,4,5,5,3,5,5; CONSTBYTEINTEGERARRAY OPVAL(1:15)=20,21,27,37,30,24,22,23,25,26, 28,29,20,37,30; INTEGER RPHEAD,PASSHEAD,SAVEHEAD,REAL,REALOP,COMPLEX,C OPERATOR,OPPREC,OPND,C,D,E,RPTYPE,RPINF,BDISP,C OPNAME,OPMASK,XTRA,RPBOT,OPSTK,OPPSTK,PASSBOT RECORDNAME LCELL(LISTF) ! PASSHEAD=0; RPHEAD=0; SAVEHEAD=0 REAL=0; REALOP=0; BDISP=0 RPBOT=0; OPSTK=0; OPPSTK=0 ! C=A(P) IF 2<=C<=3 THEN START; ! INITIAL '-' OR '¬' NOPS=NOPS+1 ! '-' =(11,3) '¬' =(10,5) OPSTK=4-C OPPSTK=C<<1-1 OPMASK=1<<(19+C); ! - %OR !! FINISH ELSE OPMASK=0 NEXTOPND:OPND=A(P+1); P=P+2 COMPLEX=0; XTRA=0 -> OPERAND(OPND); ! SWITCH ON OPERAND OPERAND(1): ! NAME OPNAME=A(P)<<8+A(P+1) LCELL==ASLIST(TAGS(OPNAME)) PTYPE=LCELL_S1>>16 IF PTYPE=X'FFFF' THEN PTYPE=7; ! NAME NOT SET TYPE=PTYPE&7; PREC=PTYPE>>4&15 IF PTYPE=SNPT THEN START D=LCELL_S3>>16 IF D=38 AND A(P+2)=2 THEN START; ! PICK OFF NL RPTYPE=0; RPINF=10; PTYPE=X'51'; P=P+2; ->SKNAM FINISH IF D=52 AND A(P+2)=2 START; ! PICK OFF PI RPTYPE=1; PTYPE=X'62'; RPINF=X'413243F6' XTRA=X'A8885A31' P=P+2; REAL=1; ->SKNAM FINISH COMPLEX=1 PTYPE=TSNAME(D); UNPACK FINISH IF PTYPE&X'FF00'=X'4000' AND A(P+2)=2=A(P+3) C AND 1<=TYPE<=2 THEN START; ! CONST VAR LCELL_S1=LCELL_S1!X'8000'; ! SET USED BIT RPINF=LCELL_S2; XTRA=LCELL_S3 RPTYPE=1; PTYPE=PTYPE&255 IF TYPE=1 AND PREC<=5 AND X'FFFE0000'<=RPINF<=X'1FFFF'C THEN RPTYPE=0 AND PTYPE=X'51' IF PREC=7 THEN RPTYPE=3 REAL=1 IF TYPE=2 P=P+2; ->SKNAM FINISH XTRA=OPNAME IF PTYPE&X'3F00'#0 OR PARMCHK=1 OR PREC<5 C THEN COMPLEX=1 AND XTRA=-1 OPMASK=OPMASK!(COMPLEX<<19) IF A(P+2)#2 OR A(P+3)#2 THEN XTRA=-1; ! XTRA=NAME FOR LOCAL SCALRS ONLY IF TYPE=3 THEN START D=P; KFORM=LCELL_S3&X'FFFF' C=COPY RECORD TAG(E); P=D; COMPLEX=1 UNLESS E=1 AND 1<=TYPE<=2 AND NAM=ARR=0 C AND PREC#3 FINISH IF PREC>=6 THEN OPMASK=OPMASK!1<<17; ! MORE THAN 32 BITS RPTYPE=2; RPINF=P; PTYPE=X'51' IF PTYPE=7 IF TYPE=5 THEN FAULT2(76,0,OPNAME) AND RPTYPE=0 AND C PTYPE=X'51' IF TYPE=2 THEN REAL=1 P=P+2 SKNAM: IF A(P)=2 THEN P=P+1 ELSE SKIP APP IF A(P)=1 THEN P=P+3 AND ->SKNAM P=P+2 INS: IF RPTYPE=2 THEN OPMASK=OPMASK!1<<18 BINSERT(RPHEAD,RPBOT,PTYPE<<16!COMPLEX<<8!RPTYPE,RPINF,XTRA) -> OP OPERAND(2): ! CONSTANT PTYPE=A(P); D=PTYPE>>4 C=PTYPE&7 IF D=4 THEN START RPINF=FROM AR2(P+1) PTYPE=X'51' FINISH ELSE RPINF=FROM AR4(P+1) REAL=1 IF C=2; RPTYPE=1 IF D=6 THEN XTRA=FROM AR4(P+5) IF C=5 THEN START; ! STRING CONSTANT FAULT2(77,0,0); RPINF=1; RPTYPE=0 P=P+A(P+5)+7; PTYPE=X'51' FINISH ELSE START IF D=7 THEN XTRA=ADDR(A(P+1)) AND RPTYPE=3 IF PTYPE=X'51' AND X'FFFE0000'<=RPINF<=X'1FFFF' THEN C RPTYPE=0 P=P+2+BYTES(D) FINISH; -> INS OPERAND(3): ! SUB EXPRESSION PASSHEAD=0; PASSBOT=0 P=P+3 TORP(PASSHEAD,PASSBOT,NOPS) REAL=1 IF TYPE=2 ! CONCAT(RPHEAD,PASSHEAD) IF RPBOT=0 THEN RPHEAD=PASSHEAD ELSE C ASLIST(RPBOT)_LINK=PASSHEAD RPBOT=PASSBOT P=P+1 OP: ! DEAL WITH OPERATOR -> EOE IF A(P-1)=2; ! EXPR FINISHED OPERATOR=A(P) ! ! THE STRING OPERATOR '.' CAUSES CHAOS IN AN ARITHMETIC EXPRSN ! SO FAULT IT AND CHANGE IT TO THE INNOCUOUS '+' ! IF OPERATOR=CONCOP THEN FAULT2(78,0,0) OPPREC=PRECEDENCE(OPERATOR) OPERATOR=OPVAL(OPERATOR) IF OPERATOR=26 OR OPERATOR=30 THEN REAL=1 NOPS=NOPS+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 BINSERT(RPHEAD,RPBOT,OPSTK&31+9,0,0) OPSTK=OPSTK>>5; OPPSTK=OPPSTK>>5 REPEAT ! ! THE CURRENT OPERATOR CAN NOW BE STORED ! OPSTK=OPSTK<<5!(OPERATOR-9) OPPSTK=OPPSTK<<5!OPPREC IF OPERATOR>=31 THEN OPERATOR=30 OPMASK=OPMASK!(1<<OPERATOR) -> NEXTOPND EOE: ! END OF EXPRESSION ! EMPTY REMAINING OPERATORS WHILE OPSTK#0 CYCLE BINSERT(RPHEAD,RPBOT,OPSTK&31+9,0,0) OPSTK=OPSTK>>5 REPEAT PTYPE=REAL+1 TYPE=PTYPE ! CONCAT(RPHEAD,HEAD) IF HEAD=0 THEN BOT=RPBOT ELSE C ASLIST(RPBOT)_LINK=HEAD HEAD=RPHEAD; ! HEAD BACK TO TOP OF LIST 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 * !* MODE HAS TYPE & PREC REQD +256 BIT IF NO RESULT REQD * !*********************************************************************** ROUTINESPEC CTOP(INTEGERNAME A) ROUTINESPEC VMY ROUTINESPEC VMY1 ROUTINESPEC CHOOSE(INTEGERNAME I) ROUTINESPEC PUT ROUTINESPEC STARSTAR ROUTINESPEC REXP ROUTINESPEC LOAD(RECORDNAME OP,INTEGER REG,MODE) ROUTINESPEC FLOAT(RECORDNAME OPND,INTEGER OTHERPTYPE) ROUTINESPEC COERCET(RECORDNAME OP1,OP2,INTEGER MODE) ROUTINESPEC COERCEP(RECORDNAME OP1,OP2) ROUTINESPEC LENGTHEN(RECORDNAME OP) ROUTINESPEC SHORTEN (RECORDNAME OP) ! INTEGERARRAY OPERAND(1:2),STK(0:99) RECORDNAME LIST(LISTF) RECORDNAME OPND1,OPND2,OPND (RD) ! INTEGER C,D,KK,JJ,OPCODE,COMM,XTRA,PP,PT,JJJ,LOADREG,EVALREG,C STPTR,CONSTFORM,CONDFORM,SAVEP CONSTINTEGERARRAY MCINST(10:37)=X'8E8E',X'F4F4E4E4',X'A8A8', X'F4F4E4E4',0(6), X'F0F0E0E0',X'F2F4E2E4', X'8E8E',X'8C8C',X'FAFAEAEA', X'AAAC',X'BABC0000', X'8A8A',X'C800'(2),X'FA000000', X'F6F6E6E6',X'00F600E6', X'2C002C00',X'02000200', X'48004800'(2),X'EA00'; CONSTBYTEINTEGERARRAY CORULES(20:37)=X'1F'(2),X'11'(2),X'1F',X'11', X'12',X'11',1,1,0,X'1F'(2), 0(4),1; 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:37) ! STPTR=0; CONSTFORM= MODE&512 CONDFORM=MODE&256 SAVEP=P EVALREG=ACCR; ! EVALUATE IN ACC UNLESS IF REG=BREG AND NOPS&X'7EC20000'=0 THEN EVALREG=BREG ! ONLY '+' %AND '*' PRESENT ! NOTHING >32 BITS NEXT: LIST==ASLIST(INHEAD) C=LIST_S1; XTRA=LIST_S2 JJ=C&255; D=INHEAD INHEAD=LIST_LINK -> OPERATOR IF JJ>=10 ! ! ANY OPERAND WHICH MAY NEED DR OR B OR ACC IN THEIR EVALUATION ! EG FUNCTIONS,ARRAY ELEMENTS ETC ARE FETCHED AND STACKKED FIRST ! OPERAND(1)=ADDR(ASLIST(D)) OPND1==ASLIST(D) IF OPND1_FLAG=2 AND OPND1_XB#0 THEN LOAD(OPND1,EVALREG,0) STK(STPTR)=OPERAND(1) STPTR=STPTR+1 ABORT IF STPTR>99 ANYMORE: ->NEXT UNLESS INHEAD=0 OR MODE=100 -> FINISH OPERATOR: IF JJ<19 THEN KK=1 ELSE KK=2; ! UNARY OR BINARY CYCLE KK=KK,-1,1 STPTR=STPTR-1 C=STK(STPTR) OPERAND(KK)=C REPEAT OPCODE=MCINST(JJ) COMM=1 OPND1 == RECORD(OPERAND(1)) OPND2 == OPND1 IF JJ>=19 THEN START OPND2==RECORD(OPERAND(2)) C=CORULES(JJ) IF C&15#0 THEN COERCET(OPND1,OPND2,C&15) IF C>>4#0 THEN COERCEP(OPND1,OPND2) FINISH IF JJ>19 START CHOOSE(COMM) OPND1==RECORD(OPERAND(COMM)) OPND2==RECORD(OPERAND(3-COMM)) FINISH PTYPE=OPND1_PTYPE; TYPE=PTYPE&7 IF TYPE=1 THEN OPCODE=OPCODE&X'FFFF' C ELSE OPCODE=OPCODE>>16; ! INTEGER OR REAL FORMS IF 2#OPND1_FLAG<4 AND 2#OPND2_FLAG<4 THEN CTOP(JJ) -> STRES IF JJ=0; ! CTOP CARRIED OUT -> SW(JJ) SW(10): ! ¬ LOAD(OPND1,EVALREG,2) FAULT(24,0) UNLESS TYPE=1 OR TYPE=7 PSF1(OPCODE&255,0,-1); ! NEQ -1 GRUSE(EVALREG)=0 SUSE: OLINK(EVALREG)=OPERAND(COMM) STRES: STK(STPTR)=OPERAND(COMM) STPTR=STPTR+1 ->ANYMORE SW(11): ! NEGATE LOAD(OPND1,EVALREG,2) IF EVALREG=BREG THEN PSF1(SLB,0,0) AND PF1(SBB,0,TOS,0) C ELSE PSF1(OPCODE&255,0,0); ! IRSB 0 OR RRSB 0 GRUSE(EVALREG)=0 -> SUSE SW(12): ! FLOAT ABORT SW(13): ! ABS LOAD(OPND1,EVALREG,2); ! OPERAND TO ACC IF TYPE=2 THEN C=2 ELSE C=6 PF3(JAF,C,0,3); ! JAF *+3 ON ACC<0 PSF1(OPCODE&255,0,0); ! IRSB 0 OR RRSB 0 GRUSE(EVALREG)=0 ->SUSE SW(14): ! STRETCH ABORT SW(20): ! ADD IF TYPE=1 AND GRUSE(EVALREG)=10 AND OPND1_FLAG=2 C AND OPND2_FLAG=0 AND REGISTER(EVALREG)=0 START P=OPND1_D; D=GRINF1(EVALREG) IF FROMAR2(P)=D&X'FFFF' AND A(P+2)=2=A(P+3) START IF EVALREG=ACCR THEN C=IAD ELSE C=ADB PSF1(C,0,OPND2_D-D>>16) GRINF1(EVALREG)=D&X'FFFF'!OPND2_D<<16 REGISTER(EVALREG)=1 OPND1_FLAG=9; OPND1_XB=EVALREG<<4 OPND1_D=0; ->SUSE FINISH FINISH BINOP: LOAD(OPND1,EVALREG,2); LOAD(OPND2,EVALREG,1) PUT; -> SUSE SW(21): ! SUBTRACT ->BINOP SW(22): ! EXCLUSIVE OR SW(23): ! OR SW(27): ! AND ->BINOP IF TYPE=1 F24: FAULT(24,0) UNLESS TYPE=7 JJ=20; OPCODE=MCINST(20) ->BINOP; ! CHANGE OPN TO + SW(28): ! SRL IF OPND2_FLAG=0 THEN OPND2_D=-OPND2_D ELSE START LOAD(OPND2,EVALREG,2); ! OPND TO ACC PSF1(IRSB,0,0); ! AND NEGATE IT GRUSE(EVALREG)=0 FINISH SW(29): ! SLL IF OPND2_PTYPE>>4=6 THEN SHORTEN(OPND2); ! LONINT TO INT -> BINOP SW(24): ! MULT -> BINOP SW(25): ! INTEGER DIVISION ->F24 UNLESS TYPE=1 -> BINOP SW(26): ! NORMAL DIVISION -> BINOP SW(30): ! EXP IN REAL EXPRSN IF OPND1_PTYPE&7=1 THEN FLOAT(OPND1,0) IF OPND2_PTYPE&7=1 THEN STARSTAR AND ->SUSE ! REAL**REAL BY SUBROUTINE REXP; COMM=2; ->SUSE SW(37): ! EXP IN INTEGER CONTEXT STARSTAR; -> SUSE SW(31): ! COMPARISONS SW(32): ! DSIDED COMPARISONS PTYPE=OPND1_PTYPE ->Z1 IF OPND1_FLAG<=1 AND OPND1_D=0 AND JJ=31 AND C (OPND1_XTRA=0 OR PTYPE>>4=5); ! INT 0 OR LONGINT 0 -> Z2 IF OPND2_FLAG<=1 AND OPND2_D=0 AND C (OPND2_XTRA=0 OR OPND2_PTYPE>>4=5) LOAD(OPND1,EVALREG,2) LOAD(OPND2,EVALREG,1) PUT REGISTER(EVALREG)=0 BFFLAG=COMM-1; ! NOTE BACKWARDS OR FORWARDS MASK=FCOMP(XTRA+7*BFFLAG) COMM=2; ->STRES; ! 2ND OPERAND MAY BE NEEDED IN ! DOUBLE SIDED AND IS THEREFORE ! TAKEN AS THE 'RESULT' Z1: COMM=3-COMM Z2: OPND==RECORD(OPERAND(COMM)) C=EVALREG; D=EVALREG!!7 IF OPND_FLAG=2 AND GRUSE(D)=9 AND C (GRINF1(D)&X'FFFF'=OPND_XTRA OR GRINF1(D)>>16=OPND_XTRA) C THEN C=D LOAD(OPND,C,2) REGISTER(C)=0 MASK=FCOMP(XTRA+7*COMM+7) IF TYPE=1 THEN MASK=MASK+4 IF C=BREG THEN MASK=MASK+8 COMM=2; ->STRES SW(33): ! SPECIAL MH FOR ARRAY ACCESS C=OPND2_D>>24; ! CURRENT DIMENSION D=OPND2_D>>16&31; ! TOTAL NO OF DIMENSIONS IF D=1 THEN VMY1 ELSE VMY IF OPND1_FLAG>1 THEN C OLINK(LOADREG)=OPERAND(COMM);! IF RESULT THEN PROTECT IT IF C=1 THEN ->STRES ->ANYMORE SW(34): ! ->LAB MASKS AND LAB AS OPND2 ! OPND1 MIDDLE OF D-SIDED ABORT SW(35): ! ASSIGN(=) SW(36): ! ASSIGN(<-) PT=OPND2_PTYPE; PP=OPND2_D IF PT&7=1 AND OPND1_PTYPE&7=2 THEN FAULT(24,0) IF PT&7=2 AND OPND1_PTYPE&7=1 THEN FLOAT(OPND1,OPND2_PTYPE) LOAD(OPND1,EVALREG,2); ! RHS TO ACC REGISTER(EVALREG)=2 C=PT>>4; D=OPND1_PTYPE>>4 IF C<5 THEN C=5 IF D<5 THEN D=5 LENGTHEN(OPND1) AND D=OPND1_PTYPE>>4 WHILE D<C WHILE (C<D AND TYPE=1 AND JJ#36) OR C<D-1 CYCLE SHORTEN(OPND1) D=OPND1_PTYPE>>4 REPEAT P=PP; CNAME(1,0); ! STORE CALL D=DISP; C=ACCESS; JJJ=AREA; ! SAVE INFO FOR STORE KK=PREC LOAD(OPND1,EVALREG,2); ! IN CASE STACKED IF JJ=36 AND TYPE=1 START IF 3<=XTRA<=4 THEN PF1(AND,0,0,(-1)>>(8*(6-XTRA)))C AND GRUSE(ACCR)=0 IF KK<=5 AND PREC=6 THEN C PSF1(MPSR,0,17) AND GRUSE(ACCR)=0 FINISH IF TYPE=2 AND KK<PREC THEN KK=STUH ELSE KK=ST IF EVALREG=BREG THEN KK=STB PSORLF1(KK,C,JJJ,D) IF (C&1=0 AND STNAME>0) OR (C=3 AND STNAME>>16>0) THEN C NOTE ASSMENT(EVALREG,JJ-33,STNAME) IF C>=2 AND JJJ#7 START; ! DR WILL BE LOADED SY STORE IF STNAME>0 THEN GRUSE(DR)=7 AND C GRINF1(DR)=STNAME&X'FFFF' ELSE GRUSE(DR)=0 FINISH IF KK=STUH THEN GRUSE(ACCR)=0 COMM=1; ->STRES FINISH: C=STK(STPTR-1) OPERAND(1)=C OPND1==RECORD(C) IF OPND1_PTYPE>>4&15<5 THEN C OPND1_PTYPE=OPND1_PTYPE&X'F'!X'50';! BITS&BYTES->INTEGERS IF CONDFORM=0 START; ! IN CONDS ONLY CC MATTERS ! SKIP GETIING OPND INRIGHT FORM ! AND IN THE RIGHT REGISTER D=MODE>>4&7; D=5 IF D<5 IF MODE&7=2 AND OPND1_PTYPE&7=1 THEN FLOAT(OPND1,D<<4) SHORTEN(OPND1) WHILE D<OPND1_PTYPE>>4 LENGTHEN(OPND1) WHILE D>OPND1_PTYPE>>4 IF CONSTFORM=0 OR 2<=OPND1_FLAG#3 THEN LOAD(OPND1,REG,2) FINISH EXPOPND=OPND1; ! SET RESULT RECORD PTYPE=OPND1_PTYPE TYPE=PTYPE&7; PREC=PTYPE>>4 IF TYPE=2 AND MODE&7=1 THEN FAULT(24,0) IF OPND1_FLAG=9 THEN REGISTER(OPND1_XB>>4)=0 P=SAVEP RETURN ! ROUTINE CHOOSE(INTEGERNAME CHOICE) RECORDNAME OPND1,OPND2(RD) OPND1==RECORD(OPERAND(1)) OPND2==RECORD(OPERAND(2)) CHOICE=1 RETURN IF JJ=21 AND EVALREG=BREG; ! NO REVERSE SUBTRACT B CHOICE=2 IF OPCODE&X'FF00FF00'=0 OR C (OPCODE&X'FF00FF'#0 AND (OPND2_FLAG=9 C OR(OPND2_FLAG=2 AND GRUSE(EVALREG)=9 AND C GRINF1(EVALREG)=OPND2_XTRA>0))) END ROUTINE LOAD(RECORDNAME OPND,INTEGER REG,MODE) !*********************************************************************** !* LOAD OPERAND OPND AS DIRECTED BY MODE TO REGISTER REG * !* MODE=0 LEAVE IN STORE IF POSSIBLE * !* MODE=1 LEAVE IN STORE IF SUITABLE FOR RX INSTRUCTIONS * !* MODE=2 LOAD TO REGISTER REGARDLESS * !*********************************************************************** INTEGER K,KK RECORDSPEC OPND(RD) SWITCH SW(0:9) K=OPND_FLAG RETURN UNLESS MODE=2 OR K=2 OR(K<=3 AND MODE=1) PTYPE=OPND_PTYPE TYPE=PTYPE&15 PREC=PTYPE>>4 IF K<0 OR K>9 THEN ABORT ->SW(K) SW(0):LITCONST: ! CONSTANT < 18 BITS AREA=0; ACCESS=0 IF PREC<=5 THEN DISP=OPND_D ELSE START DISP=OPND_XTRA ABORT UNLESS (DISP>=0 AND OPND_D=0) OR C (DISP<0 AND OPND_D=-1) FINISH IF MODE=2 THEN START; ! FETCH TO REG IF GRUSE(REG)&255=5=PREC AND GRINF1(REG)=DISP START IF REGISTER(REG)#0 THEN BOOT OUT(REG) FINISHELSE GET IN ACC(REG,BYTES(PREC)>>2,ACCESS,AREA,DISP) IF PREC<=5 THEN GRUSE(REG)=5 AND GRINF1(REG)=DISP ->LDED FINISH IF PREC=3 THEN OPND_PTYPE=X'51'; ! CONSTBYTEINTEGERS AGAIN OPND_FLAG=7; OPND_XB=AREA<<4!ACCESS OPND_D=DISP RETURN SW(1): ! LONG CONSTANT IF OPND_D=0=OPND_XTRA AND PREC<=6 THEN ->LITCONST SW(3): ! 128 BIT CONSTANT IF PREC=7 THEN KK=OPND_XTRA ELSE KK=ADDR(OPND_D) STORE CONST(DISP,BYTES(PREC),KK) IF MODE#2 THEN START OPND_FLAG=7; OPND_XB=PC<<4 OPND_D=DISP; RETURN FINISH IF GRUSE(REG)&255=6 AND GRINF1(REG)=DISP THEN START IF REGISTER(REG)#0 THEN BOOT OUT (REG) FINISH ELSE GET IN ACC(REG,BYTES(PREC)>>2,0,PC,DISP) GRUSE(REG)=6; GRINF1(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 AREA=-1 AREA=AREA CODE 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) IF PREC<5 THEN OPND_PTYPE=OPND_PTYPE&15!X'50' OPND_FLAG=9; OPND_D=0; OPND_XB=REG<<4 IF REG=BREG AND REGISTER(ACCR)&1#0 THEN C REGISTER(BREG)=2 RETURN SW(4): ! CONDITIONAL EXPRESSION SW(5): ! UNASSIGNED SW(6): ! UNASSIGNED ABORT 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(PREC)>>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 BOOT OUT(BREG) UNLESS REGISTER(BREG)=0 PF1(ST,0,BREG,0) FINISH ELSE GET IN ACC(ACCR,1,0,BREG,0) REGISTER(OPND_XB>>4)=0 OPND_XB=REG<<4; GRUSE(REG)=0 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,OCODE CODE=OPCODE IF COMM=1 THEN CODE=CODE>>8 CODE=CODE&255; OCODE=CODE IF EVALREG=BREG THEN CODE=CODE-X'C0' ABORT UNLESS OPND1_FLAG=9 PSORLF1(CODE,OPND2_XB&15,OPND2_XB>>4,OPND2_D) IF OCODE=IAD AND GRUSE(EVALREG)=9 AND OPND2_XB=0 C AND OPND2_D<4095 AND GRINF1(EVALREG)>>16=0 THEN START GRUSE(EVALREG)=10 GRINF1(EVALREG)=GRINF1(EVALREG)&X'FFFF'!OPND2_D<<16 FINISH ELSE START GRUSE(EVALREG)=0 UNLESS 31<=JJ<=32 FINISH OLINK(EVALREG)=OPERAND(COMM) END ROUTINE FLOAT(RECORDNAME OPND,INTEGER OTHERPTYPE) !*********************************************************************** !* PLANT CODE TO CONERT OPERAND FROM FIXED TO FLOATING * !*********************************************************************** RECORDSPEC OPND(RD) IF OPND_FLAG<=1 THEN START CVALUE=OPND_D OPND_D=INTEGER(ADDR(CVALUE)) OPND_XTRA=INTEGER(ADDR(CVALUE)+4) OPND_FLAG=1 FINISH ELSE START LOAD(OPND,ACCR,2) IF OTHERPTYPE&X'F0'=X'70' AND OPND_PTYPE&X'F0'<=X'50' C THEN PSF1(IMYD,0,1) AND OPND_PTYPE=OPND_PTYPE&15!X'60' PSF1(FLT,0,0) GRUSE(ACCR)=0 FINISH OPND_PTYPE=OPND_PTYPE+X'11' TYPE=2 END ROUTINE COERCET(RECORDNAME OPND1,OPND2,INTEGER MODE) !*********************************************************************** !* MODE=1 BOTH OPERANDS INTEGER ELSE ERROR * !* MODE=2 FORCE BOTH OPERAND TO BE OF TYPE REAL * !* MODE=15 BOTH OPERANDS TO BE OF LAGEST TYPE * !*********************************************************************** RECORDSPEC OPND1(RD) RECORDSPEC OPND2(RD) INTEGER PT1,PT2 PT1=OPND1_PTYPE&7 PT2=OPND2_PTYPE&7 IF (MODE=1 OR MODE=15) AND PT1=1=PT2 THEN RETURN IF MODE=1 THEN FAULT(24,0) AND RETURN IF PT1=1 THEN FLOAT(OPND1,OPND2_PTYPE) IF PT2=1 THEN FLOAT(OPND2,OPND1_PTYPE) END ROUTINE COERCEP(RECORDNAME OPND1,OPND2) !*********************************************************************** !* FORCE BOTH OPERAND TO THE SAME PRECISION BEFORE OPRNTN * !*********************************************************************** RECORDSPEC OPND1(RD) RECORDSPEC OPND2(RD) INTEGER PREC1,PREC2 PREC1=OPND1_PTYPE>>4 PREC2=OPND2_PTYPE>>4 WHILE PREC1<PREC2 CYCLE LENGTHEN(OPND1) PREC1=OPND1_PTYPE>>4 REPEAT ! WHILE PREC2<PREC1 CYCLE LENGTHEN(OPND2) PREC2=OPND2_PTYPE>>4 REPEAT END ROUTINE LENGTHEN(RECORDNAME OPND) !*********************************************************************** !* INCREASE OPND PRECISION BY ONE SIZE AT COMPILE TIME IF POSS * !*********************************************************************** RECORDSPEC OPND(RD) INTEGER TP,PR TP=OPND_PTYPE&7 PR=OPND_PTYPE>>4 IF OPND_FLAG<=1 AND PR<=4+TP START; ! LENGTHEN CONSTANT IF TP=1 AND OPND_FLAG<=1 START; ! INTEGER CONSTANT OPND_XTRA=OPND_D IF OPND_XTRA<0 THEN OPND_D=-1 ELSE OPND_D=0 FINISH ELSE START IF PR=6 THEN START TOAR8(R,LONGREAL(ADDR(OPND_D))) TOAR8(R+8,0) OPND_XTRA=ADDR(A(R)) OPND_FLAG=3 R=R+16 FINISH ELSE OPND_XTRA=0 FINISH FINISH ELSE START; ! CODE PLANTING REQRD LOAD(OPND,ACCR,2) IF TP=1 THEN PSF1(IMYD,0,1) ELSE C PF1(RMYD,0,PC,SPECIAL CONSTS(1));! REAL ONE=X'41000000' GRUSE(ACCR)=0 FINISH OPND_PTYPE=(PR+1)<<4+TP END ROUTINE SHORTEN(RECORDNAME OPND) !*********************************************************************** !* PLANT CODE TO REDUCE ACC SIZE * !*********************************************************************** RECORDSPEC OPND(RD) INTEGER TY,PR,F,I,J TY=OPND_PTYPE&7 PR=OPND_PTYPE>>4 F=OPND_FLAG IF F=3 START; ! LONGLONGREAL CONSTS CYCLE I=0,1,3 BYTEINTEGER(ADDR(J)+I)=BYTEINTEGER(OPND_XTRA+4+I) REPEAT OPND_XTRA=J OPND_FLAG=1; ! CONST NOW IN _D & _XTRA ->WAYOUT FINISH IF F<=1 START IF TY=2 THEN ->WAYOUT IF (OPND_D=0 AND OPND_XTRA>=0) OR (OPND_D=-1 AND C OPND_XTRA<0) THEN OPND_D=OPND_XTRA AND ->WAYOUT FINISH LOAD(OPND,ACCR,2) IF PR=7 THEN START; ! SHORTEN QUAD PF1(RDDV,0,PC,SPECIAL CONSTS(1)) FINISH ELSE START IF TYPE=1=PARMARR THEN PSF1(ISH,0,32) PSF1(USH,0,-32) IF PARMARR=1 OR TYPE#1 IF REGISTER(BREG)=0 THEN PF1(STUH,0,BREG,0) AND C GRUSE(BREG)=0 ELSE PSF1(MPSR,0,17); ! ACS TO 1 WORD FINISH GRUSE(ACCR)=0 WAYOUT: OPND_PTYPE=(PR-1)<<4+TY END ROUTINE EXTRACT(RECORDNAME OPND,LONGINTEGERNAME VAL, C LONGLONGREALNAME RVAL) !*********************************************************************** !* EXTRACTS A CONTANT OPERAND RETURNING REAL &INT VALUES * !*********************************************************************** RECORDSPEC OPND(RD) INTEGER TYPE,PREC,S,I,AD TYPE=OPND_PTYPE; PREC=TYPE>>4 TYPE=TYPE&15 IF TYPE=1 THEN START IF PREC<=5 THEN VAL=OPND_D ELSE START INTEGER(ADDR(VAL))=OPND_D INTEGER(ADDR(VAL)+4)=OPND_XTRA FINISH RVAL=VAL FINISH ELSE START RVAL=0 IF PREC=7 THEN S=15 AND AD=OPND_XTRA C ELSE S=7 AND AD=ADDR(OPND_D) CYCLE I=0,1,S BYTEINTEGER(ADDR(RVAL)+I)=BYTEINTEGER(AD+I) REPEAT FINISH END ROUTINE VMY1 !*********************************************************************** !* DOES VECTOR MULTIPLIES FOR ONE DIMENSION ARRAYS * !*********************************************************************** INTEGER OPNAME,VUSE,DVPOS,DVNAME,X,Y,DTYPE,DPREC,DACC,DPTYPE DPTYPE=XTRA>>16 DVNAME=XTRA&X'FFFF' DVPOS=OPND2_D&X'FFFF' IF DVPOS>0 AND OPND1_FLAG<=1 START; ! CONST ITEM & DV FOLD IT X=OPND1_D X=X-CTABLE(DVPOS+3) X=X*CTABLE(DVPOS+4) IF X<0 OR X>=CTABLE(DVPOS+5) THEN FAULT2(50,X,DVNAME) ! ! IF ARRAY BASE HAS BEEN SHIFTED TO ZERO ELEMENT PUT BACK THE LB CORRN ! NOW THE BOUND CHECK HAS BEEN COMPUTED ! IF PARMARR=0=PARMCHK AND DPTYPE&X'C0F'<=3 THEN C X=X+CTABLE(DVPOS+3)*CTABLE(DVPOS+4) OPND1_D=X RETURN FINISH OPNAME=-1 IF OPND1_FLAG=2 THEN OPNAME=OPND1_XTRA VUSE=DVNAME!OPNAME<<16 IF OPNAME>=0 AND GRUSE(BREG)=14 AND GRINF1(BREG)= C VUSE THEN ->DONE IF PARMARR=0=PARMCHK AND DVPOS>0 START LOAD(OPND1,BREG,2) X=CTABLE(DVPOS+4) IF X#1 THEN PSF1(MYB,0,X) AND GRUSE(BREG)=0 Y=X*CTABLE(DVPOS+3) IF DPTYPE&X'C0F'<=3 THEN START IF X#1 THEN ->DONE ->OUT FINISH ! TEST NAM=0 WHEN ZERO ADJSTD IF Y#0 THEN PSF1(SBB,0,Y) AND GRUSE(BREG)=0 ->DONE FINISH IF PARMARR=0=PARMCHK AND (DPTYPE&X'300'=X'200' OR C DPTYPE&X'C0F'<=3 OR COMPILER#0)START; ! IE ARR=2 OR NAM=0 DTYPE=DPTYPE&15; DPREC=DPTYPE>>4&7 LOAD (OPND1,BREG,2) UNLESS OPND1_FLAG<=1 IF DTYPE>=3 OR DPREC=4 THEN START DACC=LIST_S3; ! PUT THERE BY CANAME IF OPND1_FLAG<=1 THEN OPND1_D=OPND1_D*DACC AND RETURN PSF1(MYB,0,DACC) UNLESS DACC=1 GRUSE(BREG)=0 ->DONE FINISH IF OPND1_FLAG<=1 THEN RETURN LOADREG=BREG; ->OUT FINISH IF OPND1_FLAG=9 AND OPND1_XB>>4=ACCR THEN START PF1(ST,0,TOS,0); ! ACC CANNOT BE USED IN DVM CHANGE RD(ACCR) REGISTER(ACCR)=0 FINISH ! BASE=OPND2_XTRA>>18; AREA=-1 GET IN ACC(DR,2,0,AREA CODE,OPND2_XTRA&X'1FFFF'+8) ! LOAD(OPND1,EVALREG,0) IF OPND1_PTYPE>>4>=6 THEN FAULT(24,0) IF REGISTER(BREG)>=1 AND (OPND1_FLAG#9 OR OPND1_XB>>4#BREG) C THEN START OPND==RECORD(OLINK(BREG)) OPND_D=0 REGISTER(BREG)=2 BOOT OUT(BREG) FINISH AREA=OPND1_XB>>4; ACCESS=OPND1_XB&15 PSORLF1(OPCODE>>8,ACCESS,AREA,OPND1_D) GRUSE(BREG)=0 DONE: IF OPNAME>=0 THEN START GRUSE(BREG)=14 GRINF1(BREG)=VUSE GRINF2(BREG)=0 FINISH OUT: LOADREG=BREG REGISTER(LOADREG)=1 OPND1_FLAG=9; OPND1_XB=LOADREG<<4 END ROUTINE VMY !*********************************************************************** !* DOES ALL VECTOR MULTIPLIES EXCEPT ONE DIMENSION * !*********************************************************************** IF OPND1_FLAG=9 AND OPND1_XB>>4=ACCR THEN START PF1(ST,0,TOS,0); ! 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) IF OPND1_PTYPE>>4>=6 THEN FAULT(24,0) IF C=D AND REGISTER(BREG)>=1 AND C (OPND1_FLAG#9 OR OPND1_XB>>4#BREG) THEN START OPND==RECORD(OLINK(BREG)) OPND_D=0 REGISTER(BREG)=2 BOOT OUT(BREG) FINISH AREA=OPND1_XB>>4; ACCESS=OPND1_XB&15 PSORLF1(OPCODE>>8,ACCESS,AREA,OPND1_D) GRUSE(BREG)=0 ! LOADREG=ACCR IF C=D THEN GET IN ACC(ACCR,1,0,7,0) ELSE C PF1(IAD,0,BREG,0) IF C=1 THEN START PF1(ST,0,BREG,0) REGISTER(ACCR)=0 LOADREG=BREG FINISH REGISTER(LOADREG)=1 OPND1_FLAG=9; OPND1_XB=LOADREG<<4 END ROUTINE CTOP(INTEGERNAME FLAG) !*********************************************************************** !* AN OPERATION HAS BEEN FOUND WHERE BOTH OPERANDS ARE CONSTANTS * !* THIS ROUTINE ATTEMPTS TO INTERPRET THIS OPERATION IF IT * !* CAN BE DONE SAFELY * !* ON EXIT FLAG=0 %IF OPERATION CARRIED OUT * !*********************************************************************** CONSTINTEGER TRUNCMASK=X'01300800' INTEGER K,TYPEP,PRECP,OP,TYPEPP,VAL,SVAL1,SVAL2 LONGINTEGER VAL1,VAL2 LONGLONGREAL RVAL1,RVAL2 SWITCH ISW,RSW(10:32) ON EVENT 1,2 START RETURN FINISH TYPEP=TYPE; PRECP=PTYPE>>4&15; OP=FLAG EXTRACT(OPND1,VAL1,RVAL1) EXTRACT(OPND2,VAL2,RVAL2) SVAL1<-VAL1; SVAL2<-VAL2 IF TYPEP=1 AND OP=37 THEN ->ISW37 RETURN IF OP>32 IF TYPEP=2 THEN ->RSW(OP) ELSE ->ISW(OP) ISW(10): ! ¬ VAL1=¬VAL1 INTEND: IF PRECP=6 THEN START OPND1_D<-VAL1>>32 OPND1_XTRA<-VAL1 FLAG=0 FINISH ELSE START VAL<-VAL1 IF VAL=VAL1 OR 1<<OP&TRUNCMASK=0 THEN C FLAG=0 AND OPND1_D=VAL; ! NO ARITH OFLOW CONDITION FINISH IF FLAG=0 START OPND1_PTYPE=PRECP<<4!1 IF X'FFFE0000'<=VAL1<=X'1FFFF' THEN OPND1_FLAG=0 C ELSE OPND1_FLAG=1 FINISH RETURN ISW(11): ! INTEGER NEGATE VAL1=-VAL1; -> INT END ISW(13): ! INTEGER ABS VAL1=IMOD(VAL1); -> INT END ISW(12): ! INTEGER FLOAT RVAL1=VAL1; PRECP=5+XTRA ->REAL END RSW(14): ! STRETCH REAL PRECP=PRECP+1 REAL END:OPND1_FLAG=1 OPND1_D=INTEGER(ADDR(RVAL1)) OPND1_XTRA=INTEGER(ADDR(RVAL1)+4) IF PRECP=7 THEN START OPND1_FLAG=3 OPND1_XTRA=ADDR(A(R)) CYCLE K=0,1,15 A(R)=BYTEINTEGER(ADDR(RVAL1)+K) R=R+1 REPEAT FINISH FLAG=0; OPND1_PTYPE=16*PRECP+2 RETURN ISW(14): ! STRETCH INTEGER RSW(12): ! FLOAT REAL ABORT ISW(20): ! ADD VAL1=VAL1+VAL2; -> INT END ISW(21): ! MINUS VAL1=VAL1-VAL2; -> INT END ISW(22): ! EXCLUSIVE OR VAL1=VAL1!!VAL2; -> INT END ISW(23): ! OR VAL1=VAL1!VAL2; -> INT END ISW(24): ! MULT VAL1=VAL1*VAL2; -> INT END ISW(26): RETURN; ! / DIVISION ISW(25): RETURN IF VAL2=0; ! // DIVISION VAL1=VAL1//VAL2; -> INT END ISW(27): ! AND VAL1=VAL1&VAL2; -> INT END ISW(29): ! SLL IF PRECP=6 THEN VAL1=VAL1<<SVAL2 ELSE VAL1=SVAL1<<SVAL2 ->INT END ISW(28): ! SRL IF PRECP=6 THEN VAL1=VAL1>>SVAL2 ELSE VAL1=SVAL1>>SVAL2 ->INT END ISW(31):ISW(32): ! COMPARISONS RSW(31):RSW(32): ! REAL COMPARISONS BFFLAG=COMM-1 MASK=FCOMP(XTRA+7*BFFLAG) COMM=2; FLAG=0 IF TYPE=2 THEN ->RCOMP IF (MASK&8#0 AND VAL1=VAL2) OR (MASK&4#0 AND VAL1<VAL2)C OR (MASK&2#0 AND VAL1>VAL2) THEN MASK=15 ELSE MASK=0 RETURN RCOMP: IF (MASK&8#0 AND RVAL1=RVAL2) OR (MASK&4#0 AND RVAL1<RVAL2)C OR (MASK&2#0 AND RVAL1>RVAL2) THEN MASK=15 ELSE MASK=0 RETURN RSW(11): ! NEGATE RVAL1=-RVAL1; -> REAL END RSW(13): ! ABS RVAL1=MOD(RVAL1); -> REAL END RSW(20): ! ADD RVAL1=RVAL1+RVAL2; -> REAL END RSW(21): ! SUBTRACT RVAL1=RVAL1-RVAL2; -> REAL END RSW(24): ! MULT RVAL1=RVAL1*RVAL2; -> REAL END RSW(26): ! DIVISION RETURN IF RVAL2=0; ! AVOID DIV BY ZERO RVAL1=RVAL1/RVAL2; -> REAL END ISW(30): ! '**' WITH 2 INTEGER OPERANDS ISW37: ! '****' WITH 2 INTEGER OPERAND RETURN UNLESS 0<=VAL2<=63 VAL2=1 WHILE SVAL2>0 CYCLE VAL2=VAL2*VAL1 SVAL2=SVAL2-1 RETURN IF VAL2#INTEGER(ADDR(VAL2)+4) REPEAT VAL1=VAL2; ->INT END RSW(22):RSW(23): RSW(25):RSW(27):RSW(28):RSW(29): END ROUTINE REXP !*********************************************************************** !* CALLS A PERM ROUTINE TO PERFORM REAL**REAL * !*********************************************************************** INTEGER I,PR RECORDNAME OPND(RD) IF REGISTER(BREG)>0 THEN BOOT OUT(BREG) CYCLE I=1,1,2 OPND==RECORD(OPERAND(I)) LOAD(OPND,ACCR,2) UNLESS I=1 AND OPND_FLAG=8 PR=OPND_PTYPE>>4 IF PR<6 THEN LENGTHEN(OPND) IF PR>6 THEN SHORTEN(OPND) REPEAT PPJ(0,17) END ROUTINE STARSTAR !*********************************************************************** !* PLANT IN-LINE CODE FOR EXPONENTIATION * !* IMP ALLOWS EXPONENTS IN INTEGER EXPRESSIONS FROM 0-63 AND * !* IN REAL EXPRESSIONS FROM-255 TO +255 * !*********************************************************************** INTEGER TYPEP,PRECP,WORK,C,EXPWORK,VALUE PTYPE=OPND1_PTYPE; ! INSPECT THE OPERAND UNPACK TYPEP=TYPE; PRECP=PREC IF TYPEP=2 THEN OPCODE=X'FA' ELSE OPCODE=X'EA' 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,2); ! FETCH OPERAND TO ACC IF TYPEP=2 AND PRECP=5 THEN LENGTHEN(OPND1) AND PRECP=6 ! ! OPTIMISE **2 **3 AND **4 ! IF 2<=VALUE<=4 THEN START PF1(ST,0,TOS,0) IF VALUE=3 THEN PF1(ST,0,TOS,0) PF1(OPCODE,0,TOS,0) IF VALUE=4 THEN PF1(ST,0,TOS,0) IF VALUE>2 THEN PF1(OPCODE,0,TOS,0) GRUSE(ACCR)=0 RETURN FINISH ! ! OTHERWISE STORE OPERAND IN 'WORK' AND GET HOLD OF EXPONENT ! GET WSP(WORK,BYTES(PRECP)>>2) IF TYPEP=2 THEN GET WSP(EXPWORK,1) PSF1(ST,1,WORK) REGISTER(ACCR)=0 PLABEL=PLABEL-1; ! LABEL FOR JUMPING OUT IF OPND2_PTYPE>>4=6 THEN SHORTEN(OPND2); ! LONG EXPONENT LOAD(OPND2,BREG,2); ! EXPONENT TO ANY REGISTER IF TYPEP=2 THEN PSF1(STB,1,EXPWORK) ! ! GET '1' INTO ACC IN APPROPIATE FORM ! GET IN ACC(ACCR,BYTES(PRECP+1-TYPEP)>>2,0,0,1) IF TYPEP=2 THEN PSF1(FLT,0,0) ! ! 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 PSF1(SLB,0,0) PF1(SBB,0,TOS,0) FINISH ! ! IN CHECKING MODE PLANT CODE TO CHECK RANGE OF EXPONENT ! IF PARMOPT=1 THEN START IF TYPEP=1 THEN PPJ(30,7); ! JUMP B<0 PSF1(CPB,0,64*TYPEP*TYPEP-1) PPJ(2,7) 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 IF PRECP<7 THEN PF1(RRDV,0,PC,SPECIAL CONSTS(1))ELSESTART PSF1(SLSD,0,1); PSF1(FLT,0,0) PF1(RDV,0,TOS,0) FINISH FINISH ! ! ALL OVER. REAL RESULTS ARE IN FR WORK. INT RESULTS IN GR WORK+1 ! FREE AND FORGET ANY OTHER REGISTERS ! TYPE=TYPEP; PREC=PRECP REGISTER(BREG)=0 GRUSE(ACCR)=0 GRUSE(BREG)=0 REGISTER(ACCR)=1 OPND1_PTYPE=16*PREC+TYPE OPND1_XB=0; OPND1_D=ACCR C=ENTER LAB(PLABEL,B'11'); ! LABEL AT END OF EXP ROUTINE END END; ! OF ROUTINE EXPOP ROUTINE REDUCE ENV(INTEGERNAME HEAD) !*********************************************************************** !* HEAD HAS AN ENVIRONMENT - THIS ROUTINE REMOVES ANYTHING * !* INCOMPATIBLE WITH THE CURRENT REGISTER STATE * !*********************************************************************** INTEGER NEWHEAD,I,J,K,REG,USE NEWHEAD=0 WHILE HEAD#0 CYCLE POP(HEAD,I,J,K) REG=K>>8; USE=K&255 IF USE=GRUSE(REG)&255 AND I=GRINF1(REG) THEN C PUSH(NEWHEAD,I,J,K) REPEAT HEAD=NEWHEAD END INTEGERFN CCOND(INTEGER CTO,IU,FARLAB) !*********************************************************************** !* COMPILES <IU><SC><RESTOFCOND>%THEN<UI1>%ELSE<UI2> * !* CTO=0 JUMP TO FARLAB MUST BE PLANTED IF COND UNCONDITIONAL * !* CTO#0 JUMP MAY BE OMITTED * !* IU=1 FOR %IF =2 FOR UNLESS. FARLAB TO GO ON UI2 * !* THE ROUTINE MAKES FOUR PASSES THROUGH THE CONDITION * !* PASS 1 ANALYSES THE STRUCTURE AND DECIDES TO BRANCH ON TRUE * !* (TF=2) OR ON FALSE (TF=1) FOR EACH COMPARISON * !* PASS 2 WORKS OUT WHERE THE BRANCHES OF PASS 1 SHOULD GO TO * !* PASS 3 ASSIGNS LABEL NUMBERS * !* PASS 4 EVALUATES COMPARISIONS AND PLANTS THE CODE * !* * !* ON ENTRY P POINTS TO <SC> IN<HOLE><SC><RESTOFCOND> * !* RESULT=0 CONDITION COMPILED * !* RESULT=1 UNCONDITIONALLY TO 1ST ALTERNATIVE * !* RESULT=2 UNCONDITIONALLY TO 2ND ALTERNATIVE(FARLAB) * !*********************************************************************** ROUTINESPEC WRITE CONDLIST ROUTINESPEC SKIP SC(INTEGER REVERSED) ROUTINESPEC SKIP COND(INTEGER REVERSED) INTEGERFNSPEC CCOMP ROUTINESPEC JUMP(INTEGER MASK,LAB,FLAGS) ROUTINESPEC LAB UNUSED(INTEGER LAB) ROUTINESPEC OMIT TO(INTEGER LAB) ! ! FCOMP HAS BC MASKS FOR EACH STRING COMPARATOR. ! THE FIRST 7 ARE TO BRANCH IF TRUE WITH NORMAL COMPARISON ! THE SECOND SEVEN ARE TO BRANCH IF TRUE WITH BACKWARDS COMPARISON ! CONSTBYTEINTEGERARRAY FCOMP(1:21)=8,13,5,7,10,2,7, 8,10,2,7,13,5,7, 27,0,0,43,0,0,43; ! INTEGER PIN,PP,II,L,CPTR,CMAX,LL,BITMASK,LA RECORDFORMAT CF(BYTEINTEGER TF,CMP1,CMP2,LABU,LVL,JMP,REV,SP, C INTEGER LABNO,SP1,SP2) RECORDARRAY CLIST(1:30)(CF) RECORDNAME C1,C2(CF) ! ! PASS 1. ANALYSES THE CONDITION ! PIN=P; ! SAVE INITIAL AR POINTER CPTR=1; L=3; ! LEVEL=3 TO ALLOW 2 LOWER C1==CLIST(CPTR); ! SET UP RECORD FOR FIRST CMPARSN C1=0 SKIP SC(0); ! SKIP THE 1ST CMPARSN SKIP COND(0); ! AND ANY %AND/%OR CLAUSES C1_LVL=2; ! LEVEL =-1 FOR %IF/%THEN ENTRY C1_TF=IU CMAX=CPTR+1 C1==CLIST(CMAX); C1=0 C1_LVL=1; ! LEVEL =-2 FOR ELSE ENTRY C1_TF=3-IU; ! C1_REV NEVER SET HERE (PDS HOPES) C1_LABNO=FARLAB PP=P; ! SAVE FINAL AR POINTER FAULT(209,0) IF CMAX>29; ! TOO COMPLICATED ! ! PASS 2 WORKS OUT WHERE TO JUMP TO ! THE JUMP IS FORWARD TO THE START OF THE CLAUSE WITH A DIFFERENT ! CONNECTOR (AND/OR) PROVIDED THIS IS AT A LOWER LEVEL THAN THE BRANCH ! AND ALSO AT A LOWER LEVEL THAN THE LOWEST POINT REACHED ENROUTE ! ! ALSO CONTAINS PASS 3 (TRIVIAL) ! ASSIGN LABELS WHERE LABU SHOWS THEY ARE REQUIRED ! CYCLE CPTR=1,1,CMAX-1 C1==CLIST(CPTR) L=C1_LVL; LL=L; ! LL FOR LOWEST LEVEL ENROUTE CYCLE II=CPTR+1,1,CMAX+1 C2==CLIST(II) EXIT IF C1_TF#C2_TF AND C2_LVL<LL IF C2_LVL<LL THEN LL=C2_LVL REPEAT C1_JMP=II; ! CLAUSE TO JUMP TO C2_LABU=C2_LABU+1 IF C1_CMP2#0 OR C1_CMP1=8 START; ! D-SIDED OR RESLN ! REQIUIRES A LABEL ON THE C1_LABU=C1_LABU+1; ! THE NEXT SIMPLE CONDITION FINISH IF C1_LABU#0 AND C1_LABNO<=0 THEN PLABEL=PLABEL-1 C AND C1_LABNO=PLABEL REPEAT ! ! PASS 4 GENERATE THE CODE ! MAINTAIN BIT MASK TO HELP. 2**0 JUMP TO FAR LAB PLANTED ! 2**1 JUMP TO INTERMEDIATE LAB PLANTED ! WRITE CONDLIST IF DCOMP=1 BITMASK=0 CPTR=1 CYCLE C1==CLIST(CPTR) LA=CCOMP IF LA#0 START OMIT TO(LA) IF CPTR>=CMAX THEN START IF CTO=0 THEN ENTER JUMP(15,LA,B'11') RESULT=2 FINISH C1==CLIST(CPTR) FINISH IF C1_LABNO>0 THEN II=ENTER LAB(C1_LABNO,B'11') CPTR=CPTR+1 EXIT IF CPTR>=CMAX REPEAT ! P=PP; RESULT=1 IF BITMASK&1=0 RESULT=0 ROUTINE LAB UNUSED(INTEGER LAB) !*********************************************************************** !* A LABEL IS NOT JUMPED TO AS CONDITION ALWAYS FALSE * !* REMOVE IT FROM LIST * !*********************************************************************** INTEGER I RECORDNAME C1(CF) CYCLE I=CPTR,1,CMAX-1 C1==CLIST(I) IF C1_LABNO=LAB START C1_LABU=C1_LABU-1; ! COUNT DOWN USE COUNT IF C1_LABU=0 THEN C1_LABNO=0 RETURN FINISH REPEAT END ROUTINE OMIT TO(INTEGER LAB) !*********************************************************************** !* A JUMP TURNS OUT TO BE UNCONDITIONAL. OMIT CODE FOR SKIPPED BIT * !*********************************************************************** RECORDNAME C1(CF) CYCLE C1==CLIST(CPTR) IF C1_LABNO>0 START IF C1_LABNO=LAB THEN RETURN JUMP(15,LAB,B'11') RETURN FINISH CPTR=CPTR+1 EXIT IF CPTR>=CMAX REPEAT END ROUTINE SKIP SC(INTEGER REVERSED) !*********************************************************************** !* REVERSED=1 FOR RECURSIVE CALL IN %NOT(SC) * !* SKIPS OVER A SIMPLE CONDITION. P ON ALT OF<SC> * !*********************************************************************** SWITCH SCALT(1:3) INTEGER ALT ALT=A(P); P=P+1 ->SCALT(ALT) SCALT(1): ! <EXP><COMP><EXP><SECONDSIDE> C1_SP1=P-PIN SKIP EXP C1_CMP1=A(P) C1_REV=3*REVERSED P=P+1; C1_SP2=P-PIN SKIP EXP IF A(P)=2 THEN P=P+1 ELSE START C1_CMP2=A(P+1); ! DEAL WITH 2ND HALF OF D-SIDED P=P+2; SKIP EXP FINISH RETURN SCALT(2): ! '('<SC><RESTOFCOND>')' L=L+1 SKIP SC(REVERSED) SKIP COND(REVERSED) L=L-1 RETURN SCALT(3): ! %NOT(SC) SKIP SC(REVERSED!!1) END; ! OF ROUTINE SKIP SC ROUTINE SKIP COND(INTEGER REVERSED) !*********************************************************************** !* SKIPS OVER <RESTOFCOND> * !*********************************************************************** INTEGER ALT,ALTP ALT=A(P); ! 1=%AND<ANDC>,2=%OR<ORC>,3=NULL P=P+1 IF ALT¬=3 THEN START; ! NULL ALTERNATIVE NOTHING TO DO UNTIL ALTP=2 CYCLE; ! UNTIL NO MORE <SC>S C1_LVL=L; C1_TF=ALT C1_TF=C1_TF!!(3*REVERSED) CPTR=CPTR+1 C1==CLIST(CPTR); C1=0 SKIP SC(REVERSED) ALTP=A(P); P=P+1 REPEAT FINISH END ROUTINE WRITE CONDLIST CONSTSTRING(5) ARRAY CM(0:10)=" "," ="," >="," >", " #"," <="," <"," ¬="," ->", " =="," ¬=="; PRINTSTRING(" NO TF C1 C2 LABU LVL JMP REV LABNO ") CYCLE CPTR=1,1,CMAX C1==CLIST(CPTR) WRITE(CPTR,2) WRITE(C1_TF,4) PRINTSTRING(CM(C1_CMP1)) PRINTSTRING(CM(C1_CMP2)) WRITE(C1_LABU,6) WRITE(C1_LVL,5) WRITE(C1_JMP,4) WRITE(C1_REV,4) WRITE(C1_LABNO,7) NEWLINE REPEAT END INTEGERFN CCOMP !*********************************************************************** !* COMPILES A COMPARISION: THREE DIFFERENT CASES * !* 1) ARITHMETIC EXPRESSIONS EXPOP IS USED * !* 2) STRING EXPRESSION AD-HOC CODE PLANTED BY THIS ROUTINE * !* 3) RESOLUTIONS - CRES CAN BE USED * !* 4) EQUIVALENCES INTEGER COMPARISONS ON ADDRESSES * !* RESULT=0 CODE COMPILED * !* RESULT#0 UNCODITIONAL JUMP TO LAB=RESULT * !*********************************************************************** ROUTINESPEC ACOMP(INTEGER TF,DS) ROUTINESPEC ADCOMP(INTEGER TF) ROUTINESPEC SCOMP(INTEGER DS,TF,LAB,INTEGERNAME WA) INTEGER HEAD1,HEAD2,NOPS,TE1,TE2,TEX1,TEX2,P1,P2,FEXIT,IEXIT, C CMP,WA1,WA2,WA3,BOT1,BOT2 ! HEAD1=0; HEAD2=0; NOPS=0 BOT1=0; BOT2=0 FEXIT=CLIST(C1_JMP)_LABNO; ! FINAL EXIT IEXIT=FEXIT; ! INTERMEDIATE EXIT (D-SIDED ETC) IF C1_REV!!C1_TF=2 AND (C1_CMP1=8 OR C1_CMP2#0) THEN C IEXIT=C1_LABNO ! P=PIN+C1_SP2 P2=P; P1=PIN+C1_SP1 IF C1_CMP1=8 THEN START ! CONDITIONAL RESOLUTION ! NB CRES BRANCHES ON FALSE!! P=P1 IF A(P+3)=4 AND A(P+4)=1 START P=P+5; CNAME(2,DR); ! LH STRING TO DR IF A(P)=2 THEN START IF TYPE#5 THEN FAULT2(71,0,FROMAR2(P1+5)) C AND RESULT=0 P=P2 CRES(IEXIT); ! FAILURES -> IEXIT IF IEXIT=FARLAB THEN BITMASK=BITMASK!1 ELSE C BITMASK=BITMASK!2 IF C1_REV!!C1_TF=2 THEN JUMP(15,FEXIT,B'11') RESULT=0 FINISH FINISH FAULT2(74,0,0) RESULT=0 FINISH IF C1_CMP1>8 THEN ->ADRCOMP MASK=FCOMP(C1_CMP1) TE2=TSEXP(TEX2) ->STR IF TYPE=5 ->ARITH UNLESS TE2=1 P=P1; TE1=TSEXP(TEX1) ->STR IF TYPE=5 ARITH: ! ARITHMETIC COMPARISIONS P=P1+3 TORP(HEAD1,BOT1,NOPS); ! FIRST EXPRESSION TO REVERSE POL CMP=C1_CMP1 P=P2+3 IF C1_CMP2#0 THEN START; ! IF D-SIDED DEAL WITH MIDDLE ACOMP(1,1); ! BRANCH IEXIT %IF FALSE IF MASK=15 THEN RESULT=IEXIT JUMP(MASK,IEXIT,B'11') P=P+5; ! TO THE THIRD EXPRSN CMP=C1_CMP2; ! COMPARATOR NO 2 FINISH ! ACOMP(C1_REV!!C1_TF,0); ! SECOND OR ONLY COMPARISION IF MASK=15 THEN RESULT=FEXIT JUMP(MASK,FEXIT,B'11') RESULT=0 STR: ! STRING COMPARISIONS ! SOME CARE IS NEEDED IN FREEING ! STRING WK-AREAS SET BY CSTREXP P=P1 WA1=0; WA2=0; WA3=0 IF C1_CMP2=0 AND 7<=FCOMP(C1_CMP1)<=8 AND A(P2+3)=4 AND C A(P2+4)=2 AND A(P2+5)=X'35' AND A(P2+10)=0 C AND A(P2+11)=2 THEN START CSTREXP(0,DR) MASK=FCOMP(C1_CMP1+14) IF C1_REV!!C1_TF=1 THEN MASK=REVERSE(MASK) JUMP(MASK,FEXIT,B'11') RESULT=0 FINISH CSTREXP(16,ACCR); ! DO NOT FREE WK-AREA WA1=VALUE; ! SAVE ADDRESS OF WK-AREA CMP=C1_CMP1 P=P2 ! IF C1_CMP2#0 THEN START; ! D-SIDED DEAL WITH MIDDLE SCOMP(1,1,IEXIT,WA2) P=P+2; CMP=C1_CMP2 IF WA1#0 THEN RETURN WSP(WA1,256) AND WA1=0 FINISH ! SCOMP(0,C1_REV!!C1_TF,FEXIT,WA3) CYCLE CMP=ADDR(WA1),4,ADDR(WA3) IF INTEGER(CMP)#0 THEN RETURN WSP(INTEGER(CMP),256) REPEAT RESULT=0 ADRCOMP: ! ADRESS COMPARISONS ADCOMP(C1_REV!!C1_TF) JUMP(MASK,FEXIT,B'11') RESULT=0 ROUTINE ADCOMP(INTEGER TF) !*********************************************************************** !* COMPILES AN == OR ADDRESS COMPARISON WHICH CAN NOT BE * !* DOUBLESIDED. BETTER CODE COULD BE GENERATED FOR THE * !* MOST COMMON CASE IE POINTERNAME==VARIABLE * !************************************************************************ INTEGER TYPEP,PRECP,LHNAME,RHNAME,FNAME RECORD R(RD) LHNAME=A(P1+5)<<8!A(P1+6) FNAME=RHNAME RHNAME=A(P2+5)<<8!A(P2+6) ->FLT UNLESS A(P1+3)=4 AND A(P1+4)=1 P=P1+5; CNAME(4,ACCR) ->FLT UNLESS A(P)=2; ! NO REST OF EXPR TYPEP=TYPE; PRECP=PREC REGISTER(ACCR)=1 OLINK(ACCR)=ADDR(R) R_PTYPE=1; R_XB=ACCR<<4 R_FLAG=9 ! FNAME=LHNAME ->FLT UNLESS A(P2+3)=4 AND A(P2+4)=1 P=P2+5; CNAME(4,ACCR) ->FLT UNLESS A(P)=2; ! NO REST OF EXPR FAULT2(83,LHNAME,RHNAME) UNLESS TYPEP=TYPE AND PRECP=PREC PF1(ICP,0,TOS,0) IF C1_CMP1=10 THEN MASK=7 ELSE MASK=8 IF TF=1 THEN MASK=REVERSE(MASK) RETURN FLT: REGISTER(ACCR)=0 FAULT2(80,0,FNAME) MASK=7 END ROUTINE ACOMP(INTEGER TF,DS) !*********************************************************************** !* TYPE & PREC DEFINE THE EXPRSN IN REVERSE POLISH IN HEAD1 * !* THIS ROUTINE CONVERTS THE NEXT EXPRSN TO REVERSE POLISH AND * !* ADDS OPERATORS FOR TYPE CHANGING(IF REQ) CMPRSN AND JUMP * !*********************************************************************** INTEGER PRECP,TYPEP,REG PRECP=PTYPE>>4&15; TYPEP=TYPE ! ! ADD OPERATOR AT BOTTOM. EITHER COMPARE(31) OR DS COMPARE(32) ! PUSH(HEAD2,31+DS,CMP,0) BOT2=HEAD2 NOPS=(NOPS+1)!1<<31; ! FLAG COMPARE ! ! CONVERT NEXT EXPRSN TO REVERSE POLISH AND TO THE SAME TYPE AS THE ! FIRST IF POSSIBLE. MODE=0 INTEGER IF POSSIBLE,=2 REAL, =3 LONGREAL ! TORP(HEAD2,BOT2,NOPS) IF TYPEP>TYPE THEN TYPE=TYPEP ! CONCAT(HEAD1,HEAD2) ASLIST(BOT1)_LINK=HEAD2 BOT1=BOT2; BOT2=0; HEAD2=0 EXPOP(HEAD1,-1,NOPS,256+16*PRECP+TYPE); ! PLANT THE CODE ! CLEAR LIST(HEAD1) ASLIST(BOT1)_LINK=ASL ASL=HEAD1 HEAD1=0 IF DS#0 START PUSH(HEAD1,INTEGER(ADDR(EXPOPND)),EXPOPND_D,EXPOPND_XTRA) BOT1=HEAD1 IF EXPOPND_FLAG=9 START REG=EXPOPND_D>>4 REGISTER(REG)=1 OLINK(REG)=ADDR(ASLIST(HEAD1)) FINISH FINISH IF TF=1 THEN MASK=REVERSE(MASK) END ROUTINE SCOMP(INTEGER DS,TF,LAB,INTEGERNAME WA) !*********************************************************************** !* 1ST STRING IS DEFINED BY (ACCR) * !* THIS ROUTINE EVALUATES THE NEXT STRING EXPRS AND PERFORMS * !* THE COMPARISON & BRANCH. * !* DS=0 UNLESS THIS COMPARISON IS THE FIRST HALF OF A DBLE-SIDED * !*********************************************************************** INTEGER MASK RECORD R(RD) ! REGISTER(ACCR)=1 OLINK(ACCR)=ADDR(R) R_PTYPE=1; R_XB=ACCR<<4; R_FLAG=9 MASK=FCOMP(CMP) IF TF=1 THEN MASK=REVERSE(MASK); ! REVERSE MASK TO JMP IF FALS ! CSTREXP(16,DR); ! SAVE WK-AREA WA=VALUE REGISTER(ACCR)=0 IF R_FLAG#9 THEN PF1(LSD,0,TOS,0) IF DS#0 THEN PF1(STD,0,TOS,0) PSF1(INCA,0,1); PSF1(IAD,0,1) PF2(CPS,1,1,0,0,0) GRUSE(ACCR)=0; GRUSE(DR)=0 ! ! IF CC=8 MUST CHECK THAT ACC STRING IS EXHAUSTED OTHERWISE CHANGE CC ! TO GIVE RESULT ACC>DR. THIS IS BEST FIDDLED USING ISH. ! CAN SKIP THIS CHECK IF MASK IS SUCH THAT 2**3 &2**2 BITS SET THE SAME ! IF 0#MASK&X'C'#X'C' THEN START PF3(JCC,7,0,4) PSF1(USH,0,-32) PSF1(ISH,0,-24) FINISH IF DS#0 THEN PF1(LSD,0,TOS,0); ! DOES NOT CHANGE CC JUMP(MASK,LAB,B'11') END END ROUTINE JUMP(INTEGER MASK,LAB,FLAGS) !*********************************************************************** !* CALLS ENTER JUMP WHILE MAINTAINING BITMASK * !*********************************************************************** IF MASK=0 THEN LAB UNUSED(LAB) AND RETURN ENTER JUMP(MASK,LAB,FLAGS) IF LAB=FARLAB THEN BITMASK=BITMASK!1 ELSE BITMASK=BITMASK!2 END END; ! OF CCOND 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 INTEGERFN ENTER LAB(INTEGER LAB,FLAGS) !*********************************************************************** !* 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 = USE BITS<<8 ! LABEL ADDR * !* S2 = ENVIRONMENT LIST << 16 ! UNFILLED JUMPS LIST * !* S3 = LAB NO - RESET TO FFFF WHEN USED FOR INTERNAL LABELS * !* RESULT = 1 LABEL ENTERED * !* RESULT = 0 CONDITIONAL LABEL NOT REQUIRED * !*********************************************************************** INTEGER CELL,AT,ENVHEAD,JUMPHEAD,INSTRN,OLDCELL,WORK RECORDNAME LCELL(LISTF) INTEGERNAME LHEAD CELL=LABEL(LEVEL); OLDCELL=0 WHILE CELL>0 CYCLE LCELL==ASLIST(CELL) EXIT IF LCELL_S3=LAB OLDCELL=CELL; CELL=LCELL_LINK REPEAT ! IF CELL<=0 THEN START; ! LABEL NOT KNOWN IF FLAGS&1=0 THEN START; ! UNCONDITIONAL ENTRY PUSH(LABEL(LEVEL),CA,0,LAB) FORGET(-1) RESULT=1 FINISH RESULT=0 FINISH ! ! LABEL HAS BEEN REFERENCED - FILL IN ITS ADDRESS ! IF LCELL_S1&X'FFFFFF'# 0 THEN START FAULT(2,LAB); ! LABEL SET TWICE FINISH ELSE START LCELL_S1=X'1000000'!CA FINISH ! ! SORT OUT ENVIRONMENTS - AS DIRECTED BY FLAGS ! JUMPHEAD=LCELL_S2 ENVHEAD=JUMPHEAD>>16 JUMPHEAD=JUMPHEAD&X'FFFF' IF FLAGS&2=0 THEN START FORGET(-1) CLEAR LIST(ENVHEAD) 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,WORK) PLUG(1,AT,INSTRN!(CA-AT)//2,4) REPEAT LCELL_S2=0 IF LAB> MAX ULAB THEN START IF OLDCELL=0 THEN LHEAD==LABEL(LEVEL) ELSE C LHEAD==ASLIST(OLDCELL)_LINK POP(LHEAD,AT,AT,AT) FINISH RESULT=1 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=LINE NO OF JUMP FOR DIAGNOSTICS * !* * !* 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,INSTRN RECORDNAME LCELL(LISTF) ENVHEAD=0; AT=CA IF LAB<MAX ULAB THEN FLAGS=FLAGS&X'FD'; ! NO MERGE IF LAB<21000 THEN FLAGS=FLAGS&X'FE'; ! SF OR USER LAB=LONG CELL=LABEL(LEVEL) WHILE CELL>0 CYCLE LCELL==ASLIST(CELL) IF LAB=LCELL_S3 THEN EXIT CELL=LCELL_LINK REPEAT INSTRN=MASK IF INSTRN>>8=0 THEN START JCODE=JCC IF MASK>=16 THEN JCODE=JAT IF MASK>=32 THEN JCODE=JAF INSTRN=JCODE<<24!(MASK&15)<<21 IF MASK=15 THEN INSTRN=JUNC<<24!3<<23 FINISH -> FIRSTREF IF CELL<=0 LABADDR=LCELL_S1&X'FFFFFF' -> NOT YET SET IF LABADDR=0 LCELL_S1=LABADDR!X'1000000';! FLAG LABEL AS USED I=(LABADDR-CA)//2 IF MASK=15 THEN PSF1(JUNC,0,I) ELSE C PCONST(INSTRN!(I&X'3FFFF')) RETURN FIRSTREF: ! FIRST REFERENCE TO A NEW LABEL IF LAB>MAX ULAB AND FLAGS&2#0 THEN GET ENV(ENV HEAD) PUSH(LABEL(LEVEL),X'1000000',ENVHEAD<<16,LAB) CELL=LABEL(LEVEL) LCELL==ASLIST(CELL) -> CODE NOT YET SET: ! LABEL REFERENCED BEFORE IF LAB>MAX ULAB 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 J=LCELL_S2 JJ=J&X'FFFF' PUSH(JJ,CA,INSTRN,LINE) LCELL_S2=J&X'FFFF0000'!JJ PCONST(INSTRN) END ROUTINE REMOVE LAB(INTEGER LAB) !*********************************************************************** !* REMOVES A ALBEL FROM THE CURRENT LABEL LIST WHEN KNOWN TO * !* BE REDUNDANT. MAINLY USED FOR CYCLE LABELS * !*********************************************************************** RECORDNAME LCELL(LISTF) INTEGERNAME LHEAD INTEGER CELL,AT LHEAD==LABEL(LEVEL); CELL=LHEAD WHILE CELL>0 CYCLE LCELL==ASLIST(CELL) EXIT IF LCELL_S3=LAB LHEAD==LCELL_LINK CELL=LHEAD REPEAT IF CELL>0 THEN POP(LHEAD,AT,AT,AT) 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 CYCLE I=0,1,7 GRUSE(I)=0 UNLESS C SGRUSE(I)=GRUSE(I)&255 AND SGRINF(I)=GRINF1(I) REPEAT END ROUTINE REMEMBER INTEGER I CYCLE I=0,1,7 SGRUSE(I)=GRUSE(I)&255 SGRINF(I)=GRINF1(I) REPEAT END ROUTINE CREATE AH(INTEGER MODE) !*********************************************************************** !* CREATE AN ARRAY HEAD IN TEMPORARY SPACE BY MODIFYING THE HEAD * !* THE HEAD AT AREA,ACCESS & DISP AS FOLOWS:- * !* MODE=0 (ARRAY MAPPING) ACC HAS ADDR(1ST ELEMENT) * !* MODE=1 (ARRAYS IN RECORDS) ACC HAS RELOCATION FACTOR * !*********************************************************************** INTEGER WK GET WSP(WK,4) AREA=AREA CODE IF MODE=0 THEN START IF COMPILER=1=J AND TYPE<=2 START PF1(SLSS,2,AREA,DISP+8); ! LWB TO ACC PSF1(IMY,0,-BYTES(PREC)) UNLESS PREC=3 PF1(IAD,0,TOS,0) GRUSE(DR)=0 FINISH PSORLF1(LUH,ACCESS,AREA,DISP) FINISH ELSE START PSF1(LUH,0,0) PSORLF1(IAD,ACCESS,AREA,DISP) FINISH ! PSF1(ST,1,WK); ! 1ST PART OF HEAD =DESC TO ARRAY PSORLF1(LSD,ACCESS,AREA,DISP+8) PSF1(ST,1,WK+8); ! 2ND PART = DESCPTR TO DV GRUSE(ACCR)=0 ACCESS=0; AREA=LNB; DISP=WK END ROUTINE CSNAME(INTEGER Z,REG) !*********************************************************************** !* COMPILE A SPECIAL NAME - PTYPE=10006 (=%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**5 SET FOR BUILT IN MAPPING FUNCTIONS * !* 2**4 SET IF AD-HOC CODE PLANTED BY THIS ROUTINE * !* 2**3 SET IF FIRST PARAMETER IS OF %NAME TYPE * !* 2**2-2**0 HOLD NUMBER OF PARAMS * !* * !* THE FULL SPECS ARE AS FOLLOWS:- * !* 0=%ROUTINE SELECT INPUT(%INTEGER STREAM) * !* 1=%ROUTINE SELECT OUTPUT(%INTEGER STREAM) * !* 2=%ROUTINE NEWLINE * !* 3=%ROUTINE SPACE * !* 4=%ROUTINE SKIP SYMBOL * !* 5=%ROUTINE READ STRINWG(%STRINGNAME S) * !* 6=%ROUTINE NEWLINES(%INTEGER N) * !* 7=%ROUTINE SPACES(%INTEGER N) * !* 8=%INTEGERFN NEXT SYMBOL * !* 9=%ROUTINE PRINT SYMBOL(%INTEGER SYMBOL) * !* 10=%ROUTINE READ SYMBOL(%NAME SYMBOL) * !* 11=%ROUTINE READ(%NAME NUMBER) * !* 12=%ROUTINE WRITE(%INTEGER VALUE,PLACES) * !* 13=%ROUTINE NEWPAGE * !* 14=%INTEGERFN ADDR(%NAME VARIABLE) * !* 15=%LONGREALFN ARCSIN(%LONGREAL X) * !* 16=%INTEGERFN INT(%LONGREAL X) * !* 17=%INTEGERFN INTPT(%LONRGREAL X) * !* 18=%LONGREALFN FRACPT(%LONGREAL X) * !* 19=%ROUTINE PRINT(%LONGREAL NUMBER,%INTEGER BEFORE,AFTER) * !* 20=%ROUTINE PRINTFL(%LONGREAL NUMBER,%INTEGER PLACES) * !* 21=%REALMAP REAL(%INTEGER VAR ADDR) * !* 22=%INTEGERMAP INTEGER(%INTEGER VAR ADDR) * !* 23=%LONGREALFN MOD(%LONGREAL X) * !* 24=%LONGREALFN ARCCOS(%LONGREAL X) * !* 25=%LONGREALFN SQRT(%LONGREAL X) * !* 26=%LONGREALFN LOG(%LONGREAL X) * !* 27=%LONGREALFN SIN(%LONGREAL X) * !* 28=%LONGREALFN COS(%LONGREAL X) * !* 29=%LONGREALFN TAN(%LONGREAL X) * !* 30=%LONGREALFN EXP(%LONGREAL X) * !* 31=%ROUTINE CLOSE STREAM(%INTEGER STREAM) * !* 32=%BYTEINTEGERMAP BYTE INTEGER(%INTEGER VAR ADDR) * !* 33=%INTEGERFN EVENTINF * !* 34=%LONGREALFN RADIUS(%LONGREAL X,Y) * !* 35=%LONGREALFN ARCTAN(%LONGREAL X,Y) * !* 36=%BYTEINTEGERMAP LENGTH(%STRINGNAME S) * !* 37=%ROUTINE PRINT STRING(%STRING(255) MESSAGE) * !* 38=%INTEGERFN NL * !* 39=%LONGREALMAP LONG REAL(%INTEGER VAR ADDR) * !* 40=%ROUTINE PRINT CH(%INTEGER CHARACTER) * !* 41=%ROUTINE READ CH(%NAME CHARACTER) * !* 42=%STRINGMAP STRING(%INTEGER VAR ADDR) * !* 43=%ROUTINE READ ITEM(%STRINGNAME ITEM) * !* 44=%STRING(1)%FN NEXT ITEM * !* 45=%BYTEINTEGERMAP CHARNO(%STRINGNAME STR,%INTEGER CHARREQD) * !* 46=%STRING(1)%FN TOSTRING(%INTEGER SYMBOL) * !* 47=%STRING(255)%FN FROMSTRING(%STRING(255)S,%INTEGER BEG,END) * !* 48=%RECORDMAP RECORD(%INTEGER REC ADDR) * !* 49=%ARRAYMAP ARRAY(%INTEGER A1ADDR,%ARRAYNAME FORMAT) * !* 50=%ROUTINE SETMARGINS(%INTEGER INOUT,LHM,RHM) * !* 51=%INTEGERFN IMOD(%INTEGER VALUE) * !* 52=%LONGREALFN PI * !* 53=%INTEGERFN EVENTLINE * !* 54=%LONGINTEGERMAP LONGINTEGER(%INTEGER ADR) * !* 55=%LONGLONGREALMAP LONGLONGREAL(%INTEGER ADR) * !* 56=%LONGINTGEREFN LENGTHENI(%INTEGER VAL) * !* 57=%LONGLONGREALFN LENGTHENR(%LONGREAL VAL) * !* 58=%INTEGERFN SHORTENI(%LONGINTEGER VAL) * !* 59=%LONGREALFN SHORTENR(%LONGLONGREAL VAL) * !* 60=%INTEGERFN NEXTCH * !* 61=%HALFINTEGERMAP HALFINTEGER(%INTEGER ADDR) * !* 62=%ROUTINE PPROFILE * !*********************************************************************** INTEGERFNSPEC OPTMAP SWITCH ADHOC(1:15) CONSTINTEGERARRAY SNINFO(0:62)=C X'41080001',X'41090001',X'408A0001',X'40A00001', X'40010001',X'800D0000',X'11010001',X'11010001', X'10020024',X'41030001',X'19030001',X'80130001', X'801B0014',X'408C0001',X'19050024',X'80010002', X'11040024',X'11040024',X'80010005',X'80090006', X'80060007',X'2100003E',X'2100003E',X'11060024', X'80010008',X'80010009',X'8001000A',X'8001000B', X'8001000C',X'8001000D',X'8001000E',X'8015000F', X'2100003E',X'100D0024',X'80030010',X'80030011', X'1907003E',X'41070001',X'10080024',X'2100003E', X'41050001',X'19030001',X'2100003E',X'19030001', X'10020024',X'1A07003E',X'11090024',X'800F0012', X'110A8018',X'120B1000',X'80170013',X'11060024', X'100C0024',X'100D0024',X'2100003E'(2), X'110E0024'(4), X'10020024',X'2100003E',X'100F0001'; CONSTSTRING(11)ARRAY SNXREFS(0:20)=C "READSTRING", "S#READ", "S#IARCSIN", "S#INT", "S#INTPT" , "S#FRACPT", "S#PRINT" , "S#PRINTFL", "S#IARCCOS","S#ISQRT" , "S#ILOG" , "S#ISIN", "S#ICOS" , "S#ITAN" , "S#IEXP" , "CLOSESTREAM", "S#IRADIUS","S#IARCTAN","FROMSTRING","SETMARGINS", "S#WRITE" ; ! ! 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. ! CONSTINTEGERARRAY SNPARAMS(0:29)=0, 1,X'62', 2,X'62',X'62', 2,X'62',X'51', 3,X'62',X'51',X'51', 1,X'435', 3,X'35',X'51',X'51', 1,X'400', 1,X'51', 3,X'51',X'51',X'51', 2,X'51',X'51'; ! ROUTINESPEC RTOS(INTEGER REG) RECORD R(RD) INTEGER ERRNO,FLAG,POINTER,WREG,PIN,SNNO,SNNAME,NAPS,SNPTYPE,JJ,C XTRA,IOCPEP,B,D,SNINF,P0,OPHEAD SNNAME=FROM AR2(P) SNNO=K; ! INDEX INTO SNINFO TESTAPP(NAPS); ! COUNT ACTUAL PARAMETERS PIN=P; P=P+2 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 ! XTRA HAS INDEX INTO ARRAY OF EXTERNAL NAMES SO THAT THESE ! CAN EASILY BE CHANGED. ! IF FLAG&X'80'#0 THEN START CXREF(SNXREFS(XTRA),PARMDYNAMIC,2,JJ);! JJ SET WITH REF DISPLACEMENT IF SNNO=26 THEN LOGEPDISP=JJ IF SNNO=31 THEN EXPEPDISP=JJ OPHEAD=0; P0=SNPARAMS(POINTER) K=OPHEAD; D=1 WHILE D<=P0 CYCLE PTYPE=SNPARAMS(POINTER+D) UNPACK IF NAM=0 THEN ACC=BYTES(PREC) ELSE ACC=8 IF PTYPE=X'35' THEN ACC=256; !STRING BY VALUE INSERTAT END(OPHEAD,PTYPE<<16,ACC<<16,0) D=D+1 REPEAT I=1; J=14 OLDI=0; PTYPE=SNPTYPE K=OPHEAD; KFORM=P0 REPLACETAG(SNNAME) REPLACE2(TAGS(SNNAME),JJ); ! DIPLACEMENT INTO S2 P=PIN; CNAME(Z,REG); ! RECURSIVE CALL NEST=REG P=P-1; RETURN; ! DUPLICATES CHECK OF <ENAME> FINISH ! ! ALL ROUTINES EXCEPT THE IMPLICITS REQUIRE A CHECK 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 THEN START; ! ILLEGAL USE ERRNO=23 IF Z=0 THEN ERRNO=17 IF Z=1 OR 3<=Z<=4 THEN ERRNO=29 IF XTRA&X'F000'#0 THEN ERRNO=84 ->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; B=ACCR IF FLAG&3#0 THEN START; ! RT HAS PARAMS P=P+1 IF SNNO=37 THEN CSTREXP(0,DR) AND B=DR C ELSE CSEXP(ACCR,X'51') FINISH IF IOCPEP>127 THEN PSF1(LSS,0,IOCPEP&127) AND IOCPEP=5 IF SNNO=4 THEN PSF1(LSS,0,0); ! SKIP SYMBOL FORCE ACS=1 CIOCP(IOCPEP,B); ! PLANT CALL OF IOCP P=P+1 ->OKEXIT FINISH ! ! THE BUILT-IN MAPS (INTEGER ETC BUT NOT RECORD OR ARRAY) ! IF FLAG&X'20'#0 THEN START SNPTYPE=X'1C00'+SNPTYPE; ! ADD MAP BITS IF PARMOPT=0 AND OPTMAP#0 THEN ->OKEXIT IF Z=1 THEN BIMSTR=1; ! SPECIAL FLAG FOR STORE VIA MAP P=P+1 CSEXP(BREG,X'51'); P=P+1 IF Z=1 THEN BIMSTR=0 JJ=SNPTYPE>>4&15 DISP=MAPDES(JJ) AREA=PC; ACCESS=3 OLDI=0; ! FOR CHECK IN == ASSGNMNT ->OKEXIT FINISH ! ! ADHOC CODING IS REQUIRED FOR THE REMAINING ROUTINES APART FROM ! A CHECK FOR NAMETYPE PARAMETERS. THE SWITCH NO IS KEPT IN POINTER ! P=P+1 IF FLAG&8#0 AND(A(P+3)#4 OR A(P+4)#1 OR C A(P+FROM AR2(P+1)+1)#2) THEN ERRNO=22 AND ->ERREXIT ->ADHOC(POINTER) ADHOC(1): ! NEWLINES(=6) & SPACES(=7) CSEXP(ACCR,X'51'); ! REPITITION NO TO ACC IF SNNO=6 THEN JJ=10 ELSE JJ=32 PSF1(USH,0,8); ! SHIFT UP 8 PLACES PSF1(OR,0,JJ); ! OR SYMBOL CIOCP(17,ACCR) P=P+1 ->OKEXIT ADHOC(2): ! NEXTSYMBOL(=8) & NEXTITEM(=44) ! ALSO NEXTCH(=60) GET IN ACC(ACCR,1,0,0,0); ! PRESERVE ANY INTERMEDIATES IF SNNO=60 THEN JJ=18 ELSE JJ=2 CIOCP(JJ,ACCR); ! LEAVES THE SYMBOL IN ACC IF SNNO=44 THEN START RTOS(BREG) SNPTYPE=X'1435' AREA=PC; ACCESS=3 DISP=MAPDES(3) FINISH NEST=ACCR; ! CONVERT R1 TO STRING ->OKEXIT ADHOC(3): ! READSYMBOL(=10),CH(=41)&ITEM(=43) IF SNNO=41 THEN JJ=4 ELSE JJ=1 PSF1(LSS,0,0) CIOCP(JJ,ACCR); ! SYMBOL OR CH TO GR1 P=P+5 IF SNNO=43 THEN START TYPE=5; RTOS(ACCR) PF1(LUH,0,PC,PARAM DES(3)) FINISH ELSE START REGISTER(ACCR)=1; TYPE=1 FINISH JJ=TYPE ASSIGN(6,P); ! BY '=' TO PARAMETER P=PIN+6+FROM AR2(PIN+4) ->OKEXIT ADHOC(4): ! INT(=16) AND INTPT (=17) CSEXP(ACCR,X'62') IF SNNO=16 THEN PF1(RAD,0,PC,SPECIAL CONSTS(0)); ! RAD 0.5 IF PARMOPT=0 THEN PSF1(RSC,0,55) AND PSF1(RSC,0,-55) IF REGISTER(BREG)#0 THEN BOOT OUT(BREG) 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) GRUSE(ACCR)=0; GRUSE(BREG)=0 NEST=ACCR P=P+1 ->OKEXIT ADHOC(5): ! ADDR(=14) P=P+5; CNAME(4,REG); ! FETCH ADDRESS MODE NEST=REG P=P+2; ->OKEXIT ADHOC(6): ! MOD(=23), IMOD(=51) IF SNNO=51 THEN START JJ=X'51'; B=5; D=IRSB XTRA=3; WREG=ACCR IF REG=BREG START B=13; D=SLB; XTRA=4; WREG=BREG FINISH FINISH ELSE START JJ=X'62'; B=1; D=RRSB XTRA=3; WREG=ACCR FINISH CSEXP(WREG,JJ); ! INTEGER OR LONGREAL MODE PF3(JAT,B,0,XTRA); ! JUMP ACC >0 PSF1(D,0,0) IF WREG=BREG THEN PF1(SBB,0,TOS,0) GRUSE(WREG)=0 NEST=WREG P=P+1 ->OKEXIT ADHOC(7): ! CHARNO(=45) & LENGTH(=36) P=P+5 IF PARMARR#0 AND SNNO=45 THEN CNAME(Z,DR) C ELSE CNAME(4,BREG) ERRNO=22 ->ERREXIT UNLESS TYPE=5 AND ROUT=0 P=P+2 IF SNNO#36 THEN START IF PARMARR=0=PARMCHK THEN START PF1(STB,0,TOS,0) CSEXP(BREG,X'51') PF1(ADB,0,TOS,0) FINISH ELSE START; ! FRIG BND CHECK FOR PARM=ARR GET WSP(JJ,2) IF Z=2 OR Z=5 THEN B=INCA ELSE B=MODD PSF1(B,0,1) PSF1(STD,1,JJ) CSEXP(BREG,X'51') PSF1(LD,1,JJ) PSF1(SBB,0,1) PF1(MODD,0,BREG,0) GRUSE(DR)=0 PSF1(ADB,1,JJ+4) FINISH P=P+1 GRUSE(BREG)=0 FINISH DISP=MAPDES(3) AREA=PC; ACCESS=3 STNAME=-1 IF Z=1; ! CANT REMEBER NAME SNPTYPE=SNPTYPE+X'1C00' ->OKEXIT ADHOC(12): ! PI(=52) ADHOC(8): ! NL(=38). THIS FN IS PICKED OFF NEST=0; ! IN CSEXP.ONLY COMES HERE IN P=P+1 ->OKEXIT; ! ERROR EG NL=A+B ADHOC(9): ! TOSTRING(=46) CSEXP(ACCR,X'51'); ! RET EXPSN P=P+1 RTOS(BREG) DISP=MAPDES(3) AREA=PC; ACCESS=3 SNPTYPE=SNPTYPE+X'1C00' ->OKEXIT ADHOC(10): ! RECORD(=48) IF RECTB=0 THEN JJ=X'1800FFFF' AND STORECONST(RECTB,4,ADDR(JJ)) IF REG=ACCR THEN START CSEXP(ACCR,X'51') PF1(LUH,0,PC,RECTB) FINISH ELSE START CSEXP(BREG,X'51') PF1(LDTB,0,PC,RECTB) PF1(LDA,0,BREG,0) FINISH P=P+1 GRUSE(REG)=0 OLDI=0; ACC=X'FFFF' SNPTYPE=SNPTYPE+X'1C00'; ! ADD MAP BITS ->OKEXIT ADHOC(11): ! ARRAY(=49) CSEXP(ACCR,X'51'); ! ADDR(A(0)) TO ACCR ERRNO=22 ->ERREXIT UNLESS A(P+4)=4 AND A(P+5)=1 REGISTER(ACCR)=1; OLINK(ACCR)=ADDR(R) R=0; R_PTYPE=X'51' R_FLAG=9; R_XB=ACCR P=P+6; CNAME(12,0) IF R_FLAG#9 THEN PF1(LSS,0,TOS,0) REGISTER(ACCR)=0 ->ERREXIT UNLESS A(P)=2 AND ARR>0 P=P+2 CREATE AH(0) RETURN ADHOC(13): ! EVENTINF(=33) & EVENTLINE D=ONINF(LEVEL) FAULT(16,SNNAME) IF D=0 D=D+4 IF SNNO#33 GET IN ACC(ACCR,1,0,LNB,D) GRUSE(ACCR)=0 NEST=ACCR ->OKEXIT ADHOC(14): ! LENGTHEN AND SHORTEN D=(SNNO&3)*8 CSEXP(ACCR,X'62517261'>>D&255) P=P+1; NEST=ACCR ->OKEXIT ADHOC(15): ! PPROFILE(IGNORED UNLESS PARM SET) PPJ(0,22) UNLESS PARMPROF=0 OKEXIT: ! NORMAL EXIT PTYPE=SNPTYPE; UNPACK RETURN ERREXIT: ! ERROR EXIT FAULT(ERRNO,SNNAME) BASE=0; DISP=0; ACCESS=0; AREA=0 P=PIN+2; SKIP APP P=P-1; RETURN INTEGERFN OPTMAP !*********************************************************************** !* LOOK FOR EXPRESSION LIKE INTEGER(ADDR(X)) AND AVOID USING DR * !*********************************************************************** INTEGER VARNAME,REXP,PP,CVAL,OP,XYNB IF 3<=Z<=4 OR SNNO=42 OR SNNO=32 OR SNNO=61 THEN RESULT=0 PP=P+2; REXP=FROM AR2(PP)+PP; ! TO REST OF EXP VARNAME=FROM AR2(PP+4); ! SHOULD BE ADDR RESULT=0 UNLESS A(PP+2)=4 AND A(PP+3)=1 COPY TAG(VARNAME); ! CHECK IT WAS ADDR ->WASADR IF PTYPE=SNPT AND K=14 AND A(PP+6)=1 ->WASLOC IF PTYPE&X'FBFF'=X'51' AND A(PP+6)=2=A(PP+7) RESULT=0 WASADR: PP=PP+10 RESULT=0 UNLESS A(PP)=4 AND A(PP+1)=1 AND C A(PP+4)=2=A(PP+5) AND A(PP+6)=2=A(PP+7) AND A(PP+8)=2 VARNAME=FROM AR2(PP+2); COPY TAG(VARNAME) RESULT=0 UNLESS PTYPE&X'FF0C'=0 IF A(REXP)=2 THEN P=REXP+2 ELSE START OP=A(REXP+1) RESULT=0 UNLESS 1<=OP<=2 AND A(REXP+2)=2 AND C A(REXP+3)=X'41' AND A(REXP+6)=2 CVAL=FROM AR2(REXP+4) IF OP=1 THEN K=K+CVAL ELSE K=K-CVAL RESULT=0 IF K<0 P=REXP+8 FINISH BASE=I DISP=K; AREA=-1; ACCESS=0 AREA=AREA CODE RESULT=1 WASLOC: ! FORM INTEGER(NAME+CONST) CVAL=0 IF A(REXP)=2 THEN PP=REXP+2 AND ->FETCH RESULT=0 UNLESS A(REXP+1)=1 AND A(REXP+2)=2 IF A(REXP+3)=X'41' AND A(REXP+6)=2 THEN C CVAL=FROM AR2(REXP+4) AND PP=REXP+8 AND ->FETCH IF A(REXP+3)=X'51' AND A(REXP+8)=2 THEN C CVAL=FROM AR4(REXP+4) AND PP=REXP+10 AND ->FETCH RESULT=0 FETCH: RESULT=0 UNLESS CVAL&3=0 AND CVAL>>20=0; ! MAX FOR XNB+N XYNB=XORYNB(9,VARNAME) UNLESS GRUSE(XYNB)=9 AND GRINF1(XYNB)=VARNAME START AREA=-1; BASE=I PSORLF1(LDCODE(XYNB),2*NAM,AREA CODE,K) GRUSE(XYNB)=9; GRINF1(XYNB)=VARNAME FINISH P=PP; AREA=XYNB ACCESS=0; DISP=CVAL RESULT=1 END ROUTINE RTOS(INTEGER REG) !*********************************************************************** !* PLANTS CODE TO CONVERT A SYMBOL IN ACC TO A ONE * !* CHARACTER STRING IN A TEMPORARARY VARIABLE. * !*********************************************************************** INTEGER KK GET WSP(KK,1); ! GET 1 WORD WK AREA STRINGL=1; DISP=KK+2 PF1(OR,0,0,256) PSF1(ST,1,KK) GET IN ACC(REG,1,0,LNB,PTR OFFSET(RBASE)) IF REG=BREG THEN KK=ADB ELSE KK=IAD PSF1(KK,0,DISP) GRUSE(BREG)=0 END END; ! OF ROUTINE CSNAME ROUTINE CANAME(INTEGER ARRP,BS,DP) !*********************************************************************** !* BS & DP DEFINE THE POSITION OF THE ARRAY HEAD * !* ARRP=1 FOR ARRAYS,2 FOR VECTORS,3 FOR ARRAYS IN RECORDS * !* BASIC DISP = DISPMNT OF A(0) FOR VECTORS OR ARRAYS IN RECORDS * !*********************************************************************** INTEGER HEAD1,HEAD2,HEAD3,NOPS,PTYPEP,KK,PP,JJ,SOLDI, C TYPEP,ARRNAME,Q,PRECP,ELSIZE,NAMINF,BOT1,BOT2,BOT3,DVD,VMYOP PP=P; TYPEP=TYPE JJ=J; PTYPEP=PTYPE; PRECP=PREC; SOLDI=OLDI IF TYPE<=2 THEN ELSIZE=BYTES(PRECP) C ELSE ELSIZE=ACC DVD=SNDISP; ! LOCATION OF DV IF CONSTANT ARRNAME=FROM AR2(P); ! NAME OF ENTITY NAMINF=TAGS(ARRNAME) FAULT(29,ARRNAME) IF ARR=3; ! ARRAYFORMAT USED AS ARRAY NAMINF=-2 AND DVD=0 IF ARRP>2; ! ARRAYS IN RECORDS TEST APP(Q); ! COUNT NO OF SUBSCRIPTS ! ! CHECK CORRECT NO OF SUBSCRIPTS PROVIDED. HOWEVER ENTITIES DECLARED ! 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 REPLACE1(TCELL,FROM1(TCELL)!Q);! DIMSN IS BOTTOM 4 BITS OF TAG JJ=Q FINISH IF JJ=Q#0 THEN START; ! IN LINE CODE ! ! 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. ! NOPS=0;HEAD1=0;HEAD2=0;HEAD3=0;! CLEAR LISTHEADS BOT1=0; BOT3=0 ! ! NOW PROCESS THE SUBSCRIPTS CALLINR TORP TO CONVERT THE EXPRESSIONS ! TO REVERSE POLISH AND ADDING THE EXTRA OPERATIONS. ! P=PP+3 CYCLE KK=1,1,JJ; ! THROUGH THE SUBSCRIPTS P=P+3; BOT2=0 TORP(HEAD2,BOT2,NOPS); ! SUBSCRIPT TO REVERSE POLISH P=P+1 ! ! MULTIPLIERS ARE DOPE VECTOR ITEMS (OPTYPE=3) ! ! N SUBSCRIPTS WILL REQUIRE (N-1) MULTIPLICATIONS AND ADDITIONS ! NOPS=(NOPS+1)!1<<24; ! DVM AS '*' PUSH(HEAD3,33,PTYPEP<<16!ARRNAME,ELSIZE);! DOPE VECTOR MULTIPLY BOT3=HEAD3 IF BOT3=0 VMYOP=KK<<24!JJ<<16!DVD PUSH(HEAD3,1<<16,VMYOP,BS<<18!DP);! MULTIPLIER IF HEAD1=0 THEN HEAD1=HEAD2 ELSE C ASLIST(BOT1)_LINK=HEAD2 BOT1=BOT2; HEAD2=0 REPEAT ! ! ADD OPERATORS TO THE BACK OF OPERANDS AND EVALUATE ! ASLIST(BOT1)_LINK=HEAD3 BOT1=BOT3 EXPOP(HEAD1,BREG,NOPS,X'251'); ! EVALUATE THE REVERSE POLISH LIST ! CONSTANT ACCEPTABLE AS RESULT ASLIST(BOT1)_LINK=ASL ASL=HEAD1 BASE=BS; DISP=DP; ACCESS=3; AREA=-1 IF EXPOPND_FLAG<=1 START; ! EVALUATED TO CONSTANT NUMMOD=EXPOPND_D; ! VALUE OF CONSTANT IF NUMMOD<0 THEN GETINACC(BREG,1,0,0,NUMMOD) ELSE C ACCESS=1; ! DESCPTR WITH CONST MODIFIER FINISH FINISH ELSE START IF JJ>Q THEN FAULT2(20,JJ-Q,ARRNAME) C ELSE FAULT2(21,Q-JJ,ARRNAME) P=P+2; SKIP APP BASE=BS; DISP=0; ACCESS=3; AREA=-1 FINISH ACC=ELSIZE PTYPE=PTYPEP; UNPACK; J=JJ OLDI=SOLDI; ! FOR NAME==A(EL) VALIDATION 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 ACCESSED BY P WHICH IS ADVANCED. * !* Z SPECIFIES ACTION AS FOLLOWS:- * !* Z=0 COMPILE A ROUTINE CALL * !* Z=1 SET ACCESS,AREA AND DISP FOR A 'STORE' OPERATION * !* Z=2 FETCH NAME TO 'REG' * !* Z=3 SET DESCRIPTOR IN REG FOR PASSING BY NAME * !* Z=4 SET 32 BIT ADDRESS OF NAME IN REG * !* Z=5 DELAYED FETCH IF NAME SIMPLE ELSE AS Z=2 * !* Z=6 STORE 'REG' (CONTAINS POINTER) INTO POINTER VARIABLE * !* Z=7->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) * !* Z=14 STORE 'REG' INTO A RECORD NAME VARIABLE * !* Z=15 SET 'REG' TO POINT TO A RECORD * !* Z=16 SET BASE AND DISP FOR RECORD * !* * !* 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, JJJ, KK, RR, LEVELP, DISPP, NAMEP, PP, SAVESL, FNAME SWITCH S, FUNNY(12:13), SW(0:8), MAP(0:3) PP=P FNAME=A(P)<<8+A(P+1) IF Z=1 OR Z=6 THEN STNAME=FNAME COPYTAG(FNAME) IF I=-1 THEN START FAULT(16, FNAME) I=RLEVEL; J=0; K=FNAME KFORM=0; SNDISP=0; ACC=4 PTYPE=7; STORE TAG(K, N) K=N; N=N+4; COPYTAG(FNAME);! SET USE BITS! FINISH SAVESL=ACC JJ=J; JJ=0 IF JJ=15 NAMEP=FNAME LEVELP=I; DISPP=K FAULT(29, FNAME) IF LITL=1 AND ROUT=0=NAM AND C (Z=1 OR Z=3 OR (Z=4 AND TYPE<5 AND ARR=0)) ->NOT SET IF TYPE=7 IF (Z=0 AND (ROUT#1 OR 0#TYPE#6)) OR (Z=13 AND ROUT=0) C THEN FAULT2(27,0,FNAME) AND ->NOT SET ->FUNNY(Z) IF Z>=10 ->RTCALL IF ROUT=1 ->SW(TYPE) SW(6): SW(4): !RECORD FORMAT NAME FAULT2(5, 0, FNAME) SW(7): NOT SET: ! NAME NOT SET NEST=0; BASE=I; DISP=K; ACCESS=0 AREA=LNB; PTYPE=1; UNPACK P=P+2; SKIP APP; ->CHKEN FUNNY(12): ! SET BASE & DISP FOR ARRAYHEAD ->SW(3) IF TYPE=3 AND (ARR=0 OR A(P+2)=1) IF PTYPE=SNPT THEN CSNAME(12,REG) AND ->CHKEN IF A(P+2)=2 THEN P=P+3 ELSE NO APP ACCESS=0; BASE=I; DISP=K; AREA=-1 ADJUST HEAD: IF ARR=1=J AND PARMARR=0=NAM AND PARMCHK=0 AND C TYPE<=3 START; ! ADJUST DESR TO 1ST ELMNT GET WSP(JJ,4) GET IN ACC(ACCR,4,ACCESS,AREA CODE,DISP) PSF1(ST,1,JJ) GET IN ACC(BREG,1,2,LNB,JJ+8); IF TYPE=3 THEN KK=ACC ELSE KK=BYTES(PREC) PSF1(MYB,0,KK) UNLESS KK=1 PSF1(LD,1,JJ) PF1(INCA,0,BREG,0); ! ADJUST DESCRPTR PSF1(STD,1,JJ) GRUSE(DR)=0; GRUSE(ACCR)=0 GRUSE(BREG)=0; AREA=LNB; DISP=JJ FINISH ->CHKEN S(12): ! ARRAYS IN RECORDS BY NAME NAMEOP(1,ACCR,16,NAMEP); ! Z=STORE TO UPDATE BASE&DISP ->ADJUST HEAD FUNNY(13): ! LOAD ADDR FOR RT-TYPE IF PTYPE=SNPT THEN CSNAME(Z,REG) AND P=P+1 AND->CHKEN DISP=MIDCELL; BASE=I IF NAM&1#0 THEN START 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 GET IN ACC(DR,2,0,SET XORYNB(-1,-1),DISP) ! PSF1(MODD,0,0); ! PROVOKE ESCAPE IF DYNAMIC FINISH ELSE START IF BASE=0 AND CPRMODE=2 START; ! IN FILE OF RTS PSF1(LD,1,12) PSF1(INCA,0,DISP) UNLESS DISP=0 GET IN ACC(ACCR,2,0,0,0) FINISH ELSE START PSF1(JLK,0,1); ! GET PC TO TOS RTJUMP(LDA,ASLIST(TAGS(FNAME))_S2);! ADD N TO POINT @ ENTRY PF1(INCA,0,TOS,0); ! AND TO DES REG JJ=X'E0000001' STORE CONST(JJJ,4,ADDR(JJ)) PF1(LDTB,0,PC,JJJ) GET IN ACC(ACCR,1,0,LNB,PTR OFFSET(BASE)) JJ=M'IMP' STORE CONST(JJJ,4,ADDR(JJ)) PF1(LUH,0,PC,JJJ); ! SPARE FIELD IN RT HDDR FINISH FINISH PF1(STD,0,TOS,0); ! DR TO TOP OF STACK PF1(LUH,0,TOS,0); ! AND TO TOP 64 BITS OF ACC GRUSE(DR)=0 FINISH IF A(P+2)=2 THEN P=P+3 ELSE NO APP; ->CHKEN SW(3): ! RECORD CRNAME(Z, REG, 2*NAM, I, -1, K, NAMEP) ->S(Z) IF Z>=10 STNAME=NAMEP IF Z=1 OR Z=6 ->STRINREC IF TYPE=5 AND Z#6 ->NOT SET IF TYPE=7 NAMEOP(Z,REG,BYTES(PREC),NAMEP) ->CHKEN SW(5): ! TYPE =STRING ! ! ALL STRING OPERATIONS ARE ON THE RELEVANT DESCRIPTOR. Z=2 &Z=5 ! REQUIRE A CURRENT LENGTH(IE MODIFIED) DESCRIPTOR. OTHER OPERATIONS ! REQUIRE THE MAX LENGTH DESCRIPTOR (IE UNMODIFIED HEADER) ! IF Z=6 THEN ->SW(1) ->STRARR IF ARR>=1 IF A(P+2)=2 THEN P=P+3 ELSE NO APP BASE=I; ACCESS=2; AREA=-1; DISP=K SNINREC: IF Z=1 THEN Z=3; ! STRINGNAMES IN RECORDS IF Z=3 OR Z=4 THEN NAMEOP(Z,REG,8,-1) AND ->CHKEN IF ACCESS=2 AND PARMCHK=0 AND REGISTER(DR)=0 START PSORLF1(LDB,2,AREA CODE,DISP);! LOAD BND & DR IN 1 INSTRN GRUSE(DR)=0 IF REG=ACCR THEN COPY DR ->CHKEN FINISH NAMEOP(3,DR,8,-1) MBND: IF PARMCHK=1 THEN TEST ASS(DR,5,8) PF1(LDB,2,7,0); ! LBOUND FIRST BYTE=CURRENT L IF REG=ACCR THEN COPY DR ->CHKEN STRARR: ! STRINGARRAYS & ARRAYNAMES CANAME(ARR, I, K) NAMEP=-1 IF Z=1 OR Z=6 THEN STNAME=NAMEP SAINREC: ! STRING ARRAYS IN RECORDS IF Z=1 OR Z=3 THEN START IF NAM=1 THEN START GET IN ACC(DR,2,0,AREA CODE,DISP+8);! DV DR ! CANAME WILL HAVE SET J=DIMEN ! FOR ALL CASES INCLUDING RECORDS PF1(SLB,1,0,1+3*(J-1)); ! STACK MODIFIER AND ! SET BREG TO STRING LENGTH FINISH GET IN ACC(DR,2,0,AREA CODE,DISP)IF AREA#7; ! ALREADY IN DR IF NAM=1 THEN START PF1(MODD,0,TOS,0) PF1(LDB,0,BREG,0) FINISH ELSE START IF ACCESS=1 THEN START PSF1(MODD,0,NUMMOD) UNLESS NUMMOD=0 FINISH ELSE START PF1(MODD,0,BREG,0) IF ACCESS=3 FINISH PSF1(LDB,0,ACC) FINISH IF REG=ACCR THEN COPY DR ->CHKEN FINISH IF Z=4 THEN NAMEOP(Z,REG,4,-1) AND ->CHKEN GET IN ACC(DR,2,0,AREA CODE,DISP) UNLESS AREA=7 IF ACCESS=1 THEN START PSF1(MODD,0,NUMMOD) UNLESS NUMMOD=0 FINISH ELSE START PF1(MODD,0,BREG,0) IF ACCESS=3 FINISH ->MBND STRINREC: ! STRINGS IN RECORDS ->SAINREC IF ARR#0 ->SNINREC IF NAM#0 OR Z=4 ! ! STRINGS IN RECORDS HAVE NO HEADER AND ARE SPECIAL ! NAMEOP(4,BREG,4,-1) PF1(LDTB,0,PC,PARAM DES(3)) PF1(LDA,0,BREG,0) PSF1(LDB,0,ACC) UNLESS Z=2 AND PARMCHK=0 GRUSE(DR)=0 ->MBND IF Z=2 COPY DR IF REG=ACCR ->CHKEN ! ! 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 START CSNAME(Z, REG); ! SPECIAL NAME ->BIM IF ROUT=1 AND NAM>=1 AND Z#0 IF TYPE#0 AND NEST=ACCR THEN ->MVFNRES ->CHKEN FINISH CRCALL(FNAME); P=P+1; ! DEAL WITH PARAMS ->CHKEN IF PTYPE&15=0 ->UDM IF NAM>1; ! MAPS UNLESS Z=2 OR Z=5 THEN START; ! FUNCTIONS FAULT(29, FNAME); BASE=0 ACCESS=0; DISP=0 FINISH MVFNRES: IF TYPE=5 THEN START; ! STRING FNS IF REG=DR THEN PF1(ST,0,TOS,0) AND PF1(LD,0,TOS,0) FINISH ELSE START IF REG=BREG THEN START BOOT OUT(BREG) IF REGISTER(BREG)#0 PF1(ST,0,BREG,0) FINISH FINISH NEST=REG; ->CHKEN UDM: ! USER DEFINED MAPS PF1(ST,0,BREG,0); ! RETURN 32 BIT ADDR IN ACC DISP=MAPDES(PREC) ACCESS=3; AREA=PC NAMEP=-1; STNAME=-1 BIM: ! BUILT IN MAPS NAMEP=-1 AND STNAME=-1 UNLESS AREA=PC AND ACCESS=3 ->CHKEN IF TYPE=3; ! MAP RECORD USE VERY LIMITED IF Z=3 OR (TYPE=5 AND Z#4) START PF1(LDTB,0,PC,DISP) IF TYPE=5 AND (PARMCHK#0 OR Z#2) THEN PSF1(LDB,0,255) PF1(LDA,0,BREG,0) GRUSE(DR)=0 FINISH ELSE START IF GRUSE(DR)=7 AND NAMEP>0 AND C GRINF1(DR)=NAMEP&X'FFFF' AND 1<=Z<=2 THEN AREA=7 ! CHANGE TO(%DR+%B) FORM FINISH ! NAM=0 KK=Z; KK=2 IF Z=5 ->MAP(KK&3) MAP(0): ! FETCH ADDRESS IF REG#BREG THEN GET IN ACC(ACCR,1,0,BREG,0) ->CHKEN MAP(1): ! STORE ->CHKEN UNLESS TYPE=5; ->MAP(3) MAP(2): ! FETCH IF TYPE=5 THEN ->MBND GET IN ACC(REG,BYTES(PREC)>>2,ACCESS,AREA,DISP) IF NAMEP>0 THEN GRUSE(DR)=7 AND GRINF1(DR)=NAMEP IF PARMCHK=1 AND PREC>=5 THEN TEST ASS(REG,1,BYTES(PREC)) ->CHKEN MAP(3): ! SET DESCRIPTOR IF TYPE=5 THEN PF1(LDB,0,0,256) COPY DR UNLESS REG=DR ->CHKEN SW(0): ! %NAME PARAMETERS NO TYPE ! ALLOW FETCH ADDR OPERATIONS ! AND SPECIAL FOR BUILTIN MAPS UNLESS 3<=Z<=4 THEN START FAULT2(90,0,FNAME); TYPE=1 FINISH SW(1): ! TYPE =INTEGER SW(2): ! TYPE=REAL IF ARR=0 OR (Z=6 AND A(P+2)=2) THEN START BASE=I; ACCESS=2*NAM DISP=K; AREA=-1 IF A(P+2)=2 THEN P=P+3 ELSE NO APP FINISH ELSE START CANAME(ARR, I, K) NAM=0 FINISH NAMEOP(Z,REG,BYTES(PREC),NAMEP) ->CHKEN ! ! GENERAL FETCHING & STORING !SECTION ! CHKEN: WHILE A(P)=1 CYCLE FAULT(69,FNAME) P=P+3; SKIP APP REPEAT P=P+1 END ROUTINE NAMEOP(INTEGER Z, REG, SIZE, NAMEP) !*********************************************************************** !* FETCH OR STORE REG FROM OR TO VARIABLE DEFINED BY AREA ACCESS * !* BASE AND DISP. * !*********************************************************************** SWITCH MOD(0:47) INTEGERFNSPEC BASEREG(INTEGER GRUSEVAL,GRINFVAL) INTEGER KK, JJJ, TOTHER, XYNB, JJ, OP1, OP2 KK=Z; KK=2 IF Z=5 IF Z=6 THEN START FAULT2(82,0,NAMEP) UNLESS NAM=1 AND ROUT=0 C AND (ACCESS>=8 OR ACCESS=2) KK=1; SIZE=8 IF ACCESS>=8 THEN ACCESS=ACCESS-4 ELSE ACCESS=0 FINISH KK=KK&3 ->MOD(ACCESS<<2!KK) ! ! AREA AND ACCESS !**** *** ****** ! THESE VARIABLES DEFINE HOW TO ACCESS ANY IMP VARIABLE. AREA HAS THE ! THREE BIT AREA CODE FROM THE PRIMARY FORMAT INSTRN.(EG 6=TOS ETC) ! THE SPECIAL CASE AREA=-1 IS USED FOR ENTITIES IN STACK FRAME 'BASE' ! THE FN AREA CODE CONVERTS THIS CASE TO AREA=LNB OR AREA=XNB ARRANGING ! TO LOAD XNB IF NECESSARY. ! ACCESS HAS TWO VERSIONS OF THE 2-BIT INDIRECTION CODE FROM PRIMARY ! FORMAT INSTRNS:- ! =0 VARIABLE DIRECTLY ADDRESSED IN 'AREA' BY 'DISP' ! =1 VARIABLE ADDRESSED BY DESCPTR AT AREA & DISP MODDED BY CONST NUMMOD ! =2 DESCRIPTOR TO VARIABLE DIRECTLY ADDRESS BY 'AREA' & 'DISP' ! =3 DESCRIPTOR AS IN =2 IS TO BE MODIFIED BY 'B' ! =4 VARIABLE 'XDISP' INTO RECORD DIRECTLY ADDRESSED BY 'AREA' & 'DISP' ! =5 VARIABLE 'XDISP' INTO RECORD ADDRESSED BY DR MODIFIED AS =1 ! =6 VAR 'XDISP' INTO RECORD ADDRESSED BY DESCRIPTOR AT 'AREA' & 'DISP' ! =7 AS =6 BUT DESCRIPTOR MODIFIED BY B ! =8-11 AS 4-7 BUT THERE IS A DESCRIPTOR TO ITEM AT 'XDISP' INTO RECORD ! THESE COVER ALL THE COMMON CASES. ITEMS LIKE ARRAYS IN RECORD ARRAYS ! NEED AN INTERMEDIATE DESCRIPTOR TO BE CALCULATED AND(USUALLY) STACKED ! ! NOTE THAT ACCESS=1 AS USED ON VARIABLES IS DIFFERENT FROM ACCESS=1 ! AS USED IN ACTUAL PLANTING ROUTINES PF1 ETC. THE CODE ACCESS=1 NEEDS ! THE RELEVANT DESCRIPOR IN DR FIRST ! ! ! AREA=7 WITH ACCESS =2 OR 3 IS USED WHEN THE DESCRIPTOR IS ALREADY ! LOADED IN DR. THIS IS AWKARD ESPECIALLY ON THE GET 32 BIT ADDR ! CASE AND NEEDS PLANTING OF IMAGE STORE FORMAT INSTRNS ! MOD(0): ! ACCESS=0 FETCH ADDRESS IF TYPE=3 THEN GETINACC(REG,1,0,AREA CODE,DISP-4) C AND RETURN GET IN ACC(REG,1,0,LNB,PTR OFFSET(BASE)) IF REG=BREG THEN JJJ=ADB ELSE JJJ=IAD PSF1(JJJ,0,DISP) IF BIMSTR=1 THEN NOTE ASSMENT(REG,3,NAMEP) RETURN MOD(1): ! ACCESS=0 STORE IF 1<=SIZE<=2 THEN START; ! BYTES & HALFS REQUIRE DESCRIPTOR PF1(LDTB,0,PC,MAP DES(SIZE+2)) UNLESS GRUSE(DR)=SIZE+11 PSF1(LDA,1,PTR OFFSET(BASE)) C UNLESS 12<=GRUSE(DR)<=13 AND GRINF1(DR)=BASE GRUSE(DR)=SIZE+11; GRINF1(DR)=BASE ACCESS=1; AREA=0 FINISH ELSE AREA=AREA CODE RETURN MOD(2): ! ACCESS=0 FETCH IF SIZE>2 AND Z=5 AND PARMCHK=0 C THEN NEST=-1 AND RETURN MOD(10): ! ACCESS=2 FETCH IF GRUSE(REG)>=9 AND NAMEP>0 THEN START IF (GRINF1(REG)=NAMEP AND GRUSE(REG)&255=9) C OR (GRINF2(REG)=NAMEP AND GRUSE(REG)>>16=9) START IF REGISTER(REG)#0 THEN BOOT OUT(REG) NEST=REG; RETURN FINISH FINISH TOTHER=REG!!7 IF GRUSE(TOTHER)>=9 AND NAMEP>0 START KK=GRINF1(TOTHER) IF (KK=NAMEP AND GRUSE(TOTHER)&255=9) C OR (GRINF2(TOTHER)=NAMEP C AND GRUSE(TOTHER)>>16=9) START IF REG=BREG AND REGISTER(BREG)=0 START PF1(ST,0,BREG,0); ! ACC TO BRGE GRUSE(REG)=GRUSE(TOTHER) GRINF1(REG)=GRINF1(TOTHER) GRINF2(REG)=GRINF2(TOTHER) NEST=REG RETURN FINISH IF REG=ACCR AND Z=2 THEN START ACCESS=0; AREA=7 SIZE=4; DISP=0 FINISH FINISH FINISH IF 1<=SIZE<=2 AND ACCESS=0 THEN START; ! BYTES PF1(LDTB,0,PC,MAP DES(SIZE+2)) UNLESS GRUSE(DR)=SIZE+11 PSF1(LDA,1,PTR OFFSET(BASE)) C UNLESS 12<=GRUSE(DR)<=13 AND GRINF1(DR)=BASE GRUSE(DR)=SIZE+11; GRINF1(DR)=BASE IF Z=5 AND PARMCHK=0 START ACCESS=1; AREA=0; NEST=-1; RETURN FINISH GET IN ACC(REG,1,1,0,DISP) IF PARMCHK#0 AND SIZE=2 C THEN TEST ASS(REG,TYPE,SIZE) NEST=REG; RETURN FINISH MOD(14): ! ACCESS=3 FETCH IF ACCESS>=2 AND(AREA=7 OR (GRUSE(DR)=7 AND NAMEP>0 C AND GRINF1(DR)=NAMEP&X'FFFF')) THEN AREA=7 AND DISP=0 C ELSE AREA=AREA CODE DRFETCH: GET IN ACC(REG,SIZE>>2,ACCESS,AREA,DISP) IF PARMCHK=1 AND SIZE#1 THEN TEST ASS(REG,TYPE,SIZE) IF (ACCESS=0 OR ACCESS=2) AND NAMEP>0 C THEN GRUSE(REG)=9 AND GRINF1(REG)=NAMEP IF ACCESS>=2 AND NAMEP>0 C THEN GRUSE(DR)=7 AND GRINF1(DR)=NAMEP&X'FFFF' NEST=REG; RETURN MOD(3): ! ACCESS=0 SET DESCRIPTOR ABORT UNLESS REG=ACCR OR REG=DR IF TYPE=3 THEN START GET IN ACC(REG,2,0,AREA CODE,DISP-8); ! PTR BEFORE START RETURN FINISH ELSE JJJ=PARAM DES(PREC) IF REG=ACCR THEN START GET IN ACC(REG,1,0,LNB,PTR OFFSET(BASE)) OP1=IAD; OP2=LUH FINISH ELSE START PSF1(LDA,1,PTR OFFSET(BASE)) OP1=INCA; OP2=LDTB FINISH PSF1(OP1,0,DISP) PF1(OP2,0,PC,JJJ) GRUSE(REG)=0 RETURN MOD(4): ! ACCESS=1 FETCH ADDRESS JJ=NUMMOD JJ=JJ*BYTES(PREC) IF PREC>4; ! HALF COME WITH BYTE MODIFIER ->MD20 MOD(20): ! ACCESS=5 FETCH ADDRESS JJ=NUMMOD+XDISP MD20: GET IN ACC(REG,1,0,AREA CODE,DISP+4);! BACK HALF OF DESCTR IF REG=ACCR THEN OP1=IAD ELSE OP1=ADB PSF1(OP1,0,JJ) UNLESS JJ=0 RETURN MOD(7): ! ACCESS=1 SET DESCRIPTOR JJ=NUMMOD JJ=JJ*BYTES(PREC) IF PREC>4; ! HALF COME WITH BYTE MODIFIER GET IN ACC(REG,2,0,AREA CODE,DISP);! DESCTR IF REG=ACCR THEN OP1=IAD ELSE OP1=INCA PSF1(OP1,0,JJ) UNLESS JJ=0 RETURN MOD(5): ! ACCESS=1 STORE MOD(6): ! ACCESS=1 FETCH IF NUMMOD=0 THEN ACCESS=2 AND ->MOD(KK+8) UNLESS GRUSE(DR)=7 AND NAMEP>0 AND GRINF1(DR)=NAMEP&X'FFFF'C THEN GET IN ACC(DR,2,0,AREA CODE,DISP) IF NAMEP>0 THEN GRUSE(DR)=7 AND GRINF1(DR)=NAMEP&X'FFFF' AREA=0; DISP=NUMMOD ->DRFETCH IF Z=2 RETURN MOD(12): ! ACCESS=3 FETCH ADDRESS JJJ=BYTES(PREC) ! ! REMEMBER HALF INTEGERS READY SCALED BY VMY OR IN CANAME ! PSF1(MYB,0,JJJ) AND GRUSE(BREG)=0 UNLESS JJJ=1 OR PREC=4 MD12: IF REG=BREG THEN START IF AREA=7 START PF1(INCA,0,BREG,0) GRUSE(DR)=0 PF1(LB,2,0,11); ! DR BTM HALF TO B VIA IMAGE STORE INSTRUCTION FINISH ELSE PF1(ADB,0,AREA CODE,DISP+4) GRUSE(BREG)=0 RETURN FINISH MOD(8): ! ACCESS=2 FETCH ADDRESS IF AREA=7 THEN GET IN ACC(REG,1,2,0,11) ELSE C GET IN ACC(REG,1,0,AREA CODE,DISP+4) IF ACCESS&3=3 THEN PF1(IAD,0,BREG,0) RETURN MOD(9): ! ACCESS=2 STORE MOD(13): ! ACCESS=3 STORE IF AREA=7 THEN DISP=0 AND RETURN IF GRUSE(DR)=7 AND NAMEP>0 AND GRINF1(DR)=NAMEP&X'FFFF' C THEN AREA=7 AND DISP=0 ELSE AREA=AREA CODE RETURN MOD(11): ! ACCESS=2 SET DESCRIPTOR IF AREA=7 THEN START COPY DR UNLESS REG=DR RETURN FINISH GET IN ACC(REG,2,0,AREA CODE,DISP) RETURN MOD(15): ! ACCESS=3 SET DESCRIPTOR GET IN ACC(DR,2,0,AREA CODE,DISP) UNLESS AREA=7 IF PREC=4 OR(TYPE=3 AND PARMARR=0) THEN JJ=INCA ELSE JJ=MODD PF1(JJ,0,BREG,0) IF REG#DR THEN COPY DR GRUSE(DR)=0 RETURN MOD(17): ! ACCESS=4 STORE MOD(18): ! ACCESS=4 FETCH IF SIZE=1 THEN DISP=DISP-8 AND ->MD2526 DISP=DISP+XDISP ACCESS=0 ->MOD(KK); ! REDUCES TO ACCESS=0 MOD(36): ! ACCESS=9 FETCH ADDRESS MOD(37): ! ACCESS=9 STORE MOD(38): ! ACCESS=9 FETCH MOD(39): ! ACCESS=9 SET DESCRIPTOR XYNB=BASEREG(8,NAMEP&X'FFFF') DISP=NUMMOD+XDISP; AREA=XYNB ACCESS=3; NAMEP=0 ->MOD(KK+8); ! HAS REDUCED TO ACCESS=2 MOD(16): ! ACCESS=4 FETCH ADDRESS DISP=DISP-8 MOD(24): ! ACCESS=6 FETCH ADDRESS GET IN ACC(REG,1,0,AREA CODE,DISP+4) IF REG=BREG THEN KK=ADB ELSE KK=IAD PSF1(KK,0,XDISP) UNLESS XDISP=0 RETURN MD2526: MOD(25): ! ACCESS=6 STORE MOD(26): ! ACCESS=6 FETCH IF SIZE>2 START XYNB=BASEREG(8,NAMEP&X'FFFF') AREA=XYNB; ACCESS=0 DISP=XDISP; ->MOD(KK) FINISH IF SIZE=1 THEN START; ! SIZE = 1 FOR BYTES PSORLF1(LD,0,AREA CODE,DISP) C UNLESS GRUSE(DR)=7 AND NAMEP>0 C AND GRINF1(DR)=NAMEP&X'FFFF' FINISH ELSE START; ! SIZE=2 FOR HALFS PF1(LDTB,0,PC,MAP DES(4)) UNLESS GRUSE(DR)=13 OR GRUSE(DR)=15 PSORLF1(LDA,0,AREA CODE,DISP+4) UNLESS C NAMEP>0 AND GRINF1(DR)=NAMEP&X'FFFF' AND C (GRUSE(DR)=7 OR GRUSE(DR)=15) FINISH GRUSE(DR)=0 IF NAMEP>0 THEN GRUSE(DR)=8*SIZE-1 AND GRINF1(DR)=NAMEP&X'FFFF' ACCESS=1; AREA=0 DISP=XDISP IF DISP=0 AND ACCESS=1 C THEN AREA=7 AND ACCESS=2 ->DRFETCH IF Z=2 RETURN MOD(23): ! ACCESS=5 SET DESCRIPTOR XDISP=NUMMOD+XDISP ->MD31 MOD(19): ! ACCESS=4 SET DESCRIPTOR DISP=DISP-8 MOD(27): ! ACCESS=6 SET DESCRIPTOR MOD(31): ! ACCESS=7 SET DESRCPTOR MD31: GET IN ACC(DR,2,0,AREA CODE,DISP) PSF1(INCA,0,XDISP) UNLESS XDISP=0 PF1(INCA,0,BREG,0) IF ACCESS=7 IF TYPE=3 OR TYPE=5 THEN PSORLF1(LDB,0,0,ACC) ELSE C PF1(LDTB,0,PC,PARAM DES(PREC)) IF REG#DR THEN COPY DR RETURN MOD(28): ! ACCESS=7 FETCH ADDRESS PSF1(ADB,0,XDISP) AND GRUSE(BREG)=0 UNLESS XDISP=0 ACCESS=3; ->MD12 MOD(29): ! ACCESS=7 STORE MOD(30): ! ACCESS=7 FETCH MOD(21): ! ACCESS=5 STORE MOD(22): ! ACCESS=5 FETCH IF 1<=SIZE<=2 THEN START IF SIZE=1 THEN START PSORLF1(LD,0,AREA CODE,DISP) UNLESS GRUSE(DR)=7 AND C NAMEP>0 AND GRINF1(DR)=NAMEP&X'FFFF' FINISH ELSE START; ! SIZE=2 HALFS PSORLF1(LDA,0,AREA CODE,DISP+4) UNLESS NAMEP>=0 C AND GRINF1(DR)=NAMEP&X'FFFF' AND C (GRUSE(DR)=7 OR GRUSE(DR)=15) PF1(LDTB,0,PC,MAPDES(4)) UNLESS C GRUSE(DR)=13 OR GRUSE(DR)=15 FINISH GRUSE(DR)=0 IF NAMEP>0 THEN GRUSE(DR)=8*SIZE-1 AND C GRINF1(DR)=NAMEP&X'FFFF' IF ACCESS=7 START PSF1(ADB,0,XDISP) IF XDISP#0 ACCESS=3; AREA=7 DISP=0 GRUSE(BREG)=0 FINISH ELSE START; ! ACCESS = 5 DISP=XDISP+NUMMOD ACCESS=1; AREA=0 FINISH NAMEP=0 ->DRFETCH IF Z=2 RETURN FINISH IF ACCESS=7 START PSORLF1(ADB,0,AREA CODE,DISP+4) GRUSE(BREG)=0 XYNB=XORYNB(0,0) PF1(LDCODE(XYNB),0,BREG,0) GRUSE(XYNB)=0 DISP=XDISP FINISH ELSE START; ! ACCESS=5 XYNB=BASEREG(8,NAMEP&X'FFFF') DISP=NUMMOD+XDISP FINISH AREA=XYNB; ACCESS=0 NAMEP=0 ->MOD(KK) MOD(32): ! ACCESS=8 FETCH ADDRESS MOD(33): ! ACCESS=8 STORE MOD(34): ! ACCESS=8 FETCH MOD(35): ! ACCESS=8 SET DESCRIPTOR DISP=DISP+XDISP NAMEP=0 ACCESS=2; ->MOD(KK+8) MOD(40): ! ACCESS=10 FETCH ADDRESS MOD(41): ! ACCESS=10 STORE MOD(42): ! ACCESS=10 FETCH MOD(43): ! ACCESS=10 SET DESCRIPTOR XYNB=BASEREG(8,NAMEP&X'FFFF') AREA=XYNB; ACCESS=2; DISP=XDISP NAMEP=0 ->MOD(KK+8) MOD(44): ! ACCESS=11 FETCH ADDRESS MOD(45): ! ACCESS=11 STORE MOD(46): ! ACCESS=11 FETCH MOD(47): ! ACCESS=11 SET DESCRIPTOR PSORLF1(ADB,0,AREA CODE,DISP+4) GRUSE(BREG)=0 XYNB=XORYNB(0,0) PF1(LDCODE(XYNB),0,BREG,0) GRUSE(XYNB)=0 NAMEP=0; AREA=XYNB ACCESS=2; DISP=XDISP; ->MOD(KK+8) INTEGERFN BASEREG(INTEGER GRUSEVAL,GRINFVAL) !*********************************************************************** !* SETS A BASE REGISTER FOR RECORD WHOSE POINTER IS AT AREA&DISP * !*********************************************************************** INTEGER XYNB IF NAMEP<=0 THEN GRUSEVAL=0 AND GRINFVAL=0 XYNB=XORYNB(GRUSEVAL,GRINFVAL) PSORLF1(LDCODE(XYNB),0,AREA CODE,DISP+4) UNLESS C GRUSE(XYNB)=GRUSEVAL>0 AND GRINF1(XYNB)=GRINFVAL GRUSE(XYNB)=GRUSEVAL GRINF1(XYNB)=GRINFVAL GRAT(XYNB)=CA RESULT=XYNB END END ROUTINE CRCALL(INTEGER RTNAME) !*********************************************************************** !* 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. * !*********************************************************************** SWITCH FPD(0:3) INTEGER II,III,QQQ,DLINK,JJ,JJJ,NPARMS,PT,LP,PSIZE,TWSP, C FPTR,TYPEP,PRECP,NAMP,TL,MOVEPTR,CLINK,RDISP RECORDNAME LCELL(LISTF) PT=PTYPE; JJJ=J; TL=OLDI TWSP=0 LP=I; CLINK=K TYPEP=TYPE; PRECP=PREC; NAMP=NAM RDISP=MIDCELL ! ! NOW CHECK THAT THE RIGHT NUMBER OF PARAMETERS HAVE BEEN PROVIDED ! TEST APP(NPARMS) P=P+2 IF KFORM#NPARMS THEN START FAULT(19,RTNAME); ! WRONG NO OF PARAMETERS GIVEN SKIP APP; P=P-1 RETURN FINISH ! SAVE IRS; ! STACK ANY IRS BEFORS ASF PSF1(PRCL,0,4) FPTR=20 ->FIRST PARM ! NEXT PARM:CLINK=LCELL_LINK FIRSTPARM:->ENTRY SEQ IF CLINK=0; ! DEPART AT ONCE IF NO PARAMS LCELL==ASLIST(CLINK) PSIZE=LCELL_S2>>16 P=P+1 PTYPE=LCELL_S1>>16 UNPACK II=TYPE;III=PREC JJ=(NAM<<1!ARR)&3 UNLESS (JJ=0 AND ROUT=0) OR C (A(P+3)=4 AND A(P+4)=1 AND A(P+FROMAR2(P+1)+1)=2) START FAULT(22,0); SKIP EXP ->NEXT PARM FINISH ! ! RT TYPE PARAMS, PASS 4 WORDS SET UP AS CODE DESC,DUMMY & ENVIRONMENT ! IF ROUT=1 THEN START II=PTYPE; P=P+5 CNAME(13,ACCR); ! SET UP 4 WDS IN ACC FAULT(22,0) IF II&255#PTYPE&255; ! PREC&TYPE SIMILAR P=P+1; MOVEPTR=16 ->STUFF FINISH ->FPD(JJ) FPD(0): ! VALUE PARAMETERS IF TYPE=5 THEN START CSTREXP(17,DR); ! TO WK AREA & KEEP WK AREA PSF1(LDB,0,PSIZE) IF REGISTER(ACCR)=3 THEN PF1(ST,0,TOS,0) C AND REGISTER(ACCR)=0 PF1(STD,0,TOS,0) PUSH(TWSP,VALUE,268,0); ! RETURN WK AREA AT CALL FPTR=FPTR+8; ->NEXT PARM FINISH ELSE START IF PREC=6 THEN JJ=3 ELSE JJ=TYPE CSEXP(ACCR,III<<4!II) MOVEPTR=((BYTES(III)+3)&(-4)) FINISH ->STUFF ! FPD(2): ! NAME PARAMETERS P=P+5 FNAME=FROM AR2(P) COPY TAG(FNAME) IF II#0 OR TYPE=0 START CNAME(3,ACCR) FAULT(22,FNAME) UNLESS II=TYPE AND III=PREC FINISH ELSE START CNAME(4,ACCR) IF TYPE<=2 THEN JJ=PREC<<27!TYPE ELSE JJ=X'1A'<<24+ACC STORE CONST(III,4,ADDR(JJ)) PF1(LUH,0,PC,III) FINISH P=P+1; MOVEPTR=8 ->STUFF ! FPD(1):FPD(3): ! ARRAY NAME (&VALUE) ! ! FOR ARRAYNAME PARAMETERS THE NO OF DIMENSIONS OF THE ARRAY IS ! DEDUCED FROM THE FIRST CALL AND STORED IN STREAM3 OF THE PARAMETER ! LIST. ON ANY SUBSEQUENT CALL ONLY ARRAYS OF THE SAME DIMENSION CAN ! BE PASSED ! P=P+5 CNAME(12,ACCR) GET IN ACC(ACCR,4,0,AREA CODE,DISP) P=P+1; MOVEPTR=16 FAULT(22,0) AND ->STUFF UNLESS 1<=ARR<=2 AND C II=TYPE AND III=PREC QQQ=FROM1(TCELL)&15; ! DIMENSION OF ACTUAL(IF KNOWN) JJ=LCELL_S1&15; ! DIMENSION OF FORMAL IF JJ=0 THEN JJ=QQQ AND LCELL_S1=LCELL_S1!JJ IF QQQ=0 THEN QQQ=JJ AND REPLACE1(TCELL,FROM1(TCELL)!JJ) FAULT(22,0) UNLESS JJ=QQQ STUFF: REGISTER(ACCR)=3 FPTR=FPTR+MOVEPTR -> NEXT PARM ENTRY SEQ: ! CODE FOR RT ENTRY IF REGISTER(ACCR)=3 THEN C PF1(ST,0,TOS,0) AND REGISTER(ACCR)=0 J=JJJ ! ! RETURN ANY STRING WSPACE HERE. CAN BE UXED AGAIN FOR RESULT ! WHILE TWSP#0 CYCLE POP(TWSP,QQQ,JJ,III) RETURN WSP(QQQ,268) REPEAT ! ! STRING FNS NEED A WORK AREA TO RETURN THEIR RESULTS ! IF TYPEP=5 AND NAMP<=1 THEN START GET WSP(QQQ,268) STRFNRES=QQQ; ! FOR CSTREXP TO USE III=X'18000100'; QQQ=QQQ+8 STORE CONST(JJ,8,ADDR(III)) PF1(LD,0,PC,JJ) PSF1(INCA,1,PTR OFFSET(RBASE)) PF1(STD,0,TOS,0) FPTR=FPTR+8 FINISH ! ! 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 NMDECS(LEVEL)=NMDECS(LEVEL)!2 II=SET XORYNB(-1,-1) PSF1(RALN,0,FPTR>>2) PF1(CALL,2,II,RDISP) FINISH ELSE START IF NAMP&1=0 THEN START; ! INTERNAL RT CALLS IF LP=0 THEN START PSF1(LD,1,12) PSF1(INCA,0,RDISP) UNLESS RDISP=0 PSF1(RALN,0,FPTR>>2) PF1(CALL,2,7,0) FINISH ELSE START; ! NORMAL INTERNAL CALL II=SET XORYNB(XNB,LP) PSF1(RALN,0,FPTR>>2) RT JUMP(CALL,ASLIST(TAGS(RTNAME))_S2) FINISH FINISH ELSE START AREA=-1; BASE=LP AREA=AREA CODE GET IN ACC(DR,2,0,AREA,RDISP);! DESCR TO DR PSORLF1(LXN,0,AREA,RDISP+12);! XNB TO ENVIRONMENT PSF1(RALN,0,FPTR>>2); ! RAISE FOR NORMAL PARAMS PF1(CALL,2,7,0) ;! AND ENTER VIA DESCRPTR IN DR FINISH FINISH FORGET(-1) ROUT=1; TYPE=TYPEP; NAM=NAMP PREC=PRECP; PTYPE=PT END ROUTINE RT JUMP(INTEGER CODE,INTEGERNAME LINK) !*********************************************************************** !* PLANTS A CALL 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 :- * !* S1(32 BITS) = INSTRN TO BE PLANTED * !* 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) PF1(CODE,0,0,0) FINISH ELSE START; ! BODY GIVEN AND ADDRESS KNOWN DP=LINK-CA DP=DP//2 IF CODE=CALL; ! CALL WORKS IN HALFWORDS! PSF1(CODE,0,DP) FINISH END INTEGERFN TSEXP(INTEGERNAME VALUE) SWITCH SW(1:3) INTEGER PP,REXP,KK,SIGN,CT TYPE=1; PP=P REXP=2-A(P+1+FROM AR2(P+1)) P=P+3 SIGN=A(P) ->TYPED UNLESS SIGN=4 OR A(P+1)=2 ->SW(A(P+1)) SW(1): ! NAME P=P+2; REDUCE TAG ->TYPED SW(2): ! CONSTANT CT=A(P+2); TYPE=CT&7 ->TYPED UNLESS CT=X'41' AND SIGN#3 KK=FROMAR2(P+3) IF REXP#0 AND A(P+6)=CONCOP THEN TYPE=5 AND ->TYPED ->TYPED UNLESS REXP=0 AND 0<=KK<=255 VALUE=KK P=P+6 IF SIGN#2 THEN RESULT=1 VALUE=-VALUE; RESULT=-1 SW(3): ! SUB EXPRN TYPED: P=PP; RESULT=0 END ROUTINE SKIP EXP !*********************************************************************** !* SKIPS OVER THE EXPRESSION POINTED AT BY P. USED FOR ERROR * !* RECOVERY AND TO EXTRACT INFORMATION ABOUT THE EXPRESSION. * !*********************************************************************** INTEGER OPTYPE, PIN, J PIN=P P=P+3; ! TO P<+'> CYCLE; ! DOWN THE LIST OF OPERATORS OPTYPE=A(P+1); ! ALT OF P<OPERAND> P=P+2 IF OPTYPE=0 OR OPTYPE>3 THEN ABORT IF OPTYPE=3 THEN SKIP EXP; ! SUB EXPRESSIONS ! IF OPTYPE=2 THEN START; ! OPERAND IS A CONSTANT J=A(P)&7; ! CONSTANT TYPE IF J=5 THEN P=P+A(P+5)+6 ELSE P=P+1+BYTES(A(P)>>4) FINISH ! IF OPTYPE=1 THEN START; ! NAME P=P-1 P=P+3 AND SKIP APP UNTIL A(P)=2 ; ! TILL NO ENAME P=P+1 FINISH ! P=P+1 IF A(P-1)=2 THEN EXIT; ! NO MORE REST OF EXP REPEAT END; ! OF ROUTINE SKIP EXP ROUTINE SKIP APP !*********************************************************************** !* SKIPS ACTUAL PARAMETER PART * !* P IS ON ALT OF P<APP> AT ENTRY * !*********************************************************************** INTEGER PIN PIN=P P=P+1 AND SKIP EXP WHILE A(P)=1 P=P+1 END ROUTINE NO APP P=P+2 IF A(P)=1 THEN START; ! <APP> PRESENT FAULT2(17,0,FROM AR2(P-2)) SKIP APP FINISH ELSE P=P+1; ! P NOW POINTS TO ENAME 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+2; ! P ON NAME AT ENTRY WHILE A(P)=1 CYCLE; ! NO (MORE) PARAMETERS P=P+1; Q=Q+1 SKIP EXP REPEAT P=PP; NUM=Q END ROUTINE TEST ASS(INTEGER REG,TYPE,SIZE) !*********************************************************************** !* TEST ACC OR B FOR THE UNASSIGNED PATTERN * !*********************************************************************** INTEGER OPCODE,A,D IF TYPE=5 THEN START RETURN UNLESS REG=DR PF1(STD,0,TOS,0) PF2(SWEQ,1,1,0,0,UNASSPAT&255) FINISH ELSE START IF REG=BREG THEN OPCODE=CPB ELSE OPCODE=UCP IF SIZE=16 THEN PF1(STUH,0,TOS,0) IF SIZE=2 THEN A=0 AND D=UNASSPAT>>16 ELSE C A=PC AND D=PLABS(1) PF1(OPCODE,0,A,D) IF SIZE=16 THEN PF1(LUH,0,TOS,0) FINISH PPJ(8,5); ! BE ERROR ROUTINE 5 IF TYPE=5 THEN PF1(LD,0,TOS,0) 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 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 IF PLACE<511 THEN PUSH(AVL WSP(SIZE,LEVEL),0,PLACE,0) C ELSE INSERT AT END(AVL WSP(SIZE,LEVEL),0,PLACE,0) END ROUTINE SETLINE !*********************************************************************** !* UPDATE THE STATEMENT NO * !*********************************************************************** INTEGER XYNB,I,LDI,STI,REG LDI=LSS; STI=ST; REG=ACCR IF PARMDBUG!PARMPROF=0 AND GRUSE(ACCR)#0 AND C (GRUSE(BREG)=0 OR GRUSE(BREG)=5) START LDI=LB; STI=STB; REG=BREG FINISH PSF1(LDI,0,LINE) IF PARMLINE!PARMDBUG#0 IF PARMLINE=1 THEN START PSF1(STI, 1, DIAGINF(LEVEL)) GRUSE(REG)=5; GRINF1(REG)=LINE FINISH IF PARMDBUG#0 THEN PPJ(0,3) IF PARMPROF#0 THEN START XYNB=SET XORYNB(-1,0); ! TO PLT PSF1(LSS,0,1) I=PARMPROF+8+4*LINE PF1(IAD,0,XYNB,I) PF1(ST,0,XYNB,I) GRUSE(ACCR)=0 FINISH END ROUTINE FORGET(INTEGER REG) INTEGER L,U L=REG; U=L IF L<0 THEN L=0 AND U=7 CYCLE REG=L,1,U IF REGISTER(REG)>= 0 THEN GRUSE(REG)=0 AND GRINF1(REG)=0 REPEAT END ROUTINE SAVE IRS !*********************************************************************** !* DUMP ACC AND-OR B ONTO THE STACK. USED BEFORE CALLING FNS * !* IN EXPRESSIONS. * !*********************************************************************** ABORT IF REGISTER(ACCR)=1=REGISTER(BREG) IF REGISTER(ACCR)>=1 THEN BOOT OUT(ACCR) IF REGISTER(BREG)>=1 THEN BOOT OUT(BREG) 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 RECORDNAME R(RD) CODE=BOOTCODE(REG) ABORT UNLESS 1<=REGISTER(REG)<=3 AND CODE#0 R==RECORD(OLINK(REG)) IF REGISTER(REG)=2 THEN START IF R_D=0 THEN GET WSP(R_D,BYTES(R_PTYPE>>4)>>2) PSF1(CODE,1,R_D) FINISH ELSE START IF REG#ACCR AND(REGISTER(ACCR)=1 OR REGISTER(ACCR)=3)C THEN BOOT OUT(ACCR) PF1(CODE,0,TOS,0) FINISH CHANGE RD(REG) 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 * !*********************************************************************** RECORDNAME OPND(RD) ABORT UNLESS 1<=REGISTER(REG)<=3; ! I-R OR PARAM OPND==RECORD(OLINK(REG)) IF REGISTER(REG)=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 REGISTER(REG)=2 START OPND_FLAG=7; OPND_XB=LNB<<4 FINISH END ROUTINE STORE TAG(INTEGER KK, SLINK) INTEGER Q, QQ, QQQ, I, TCELL RECORDNAME LCELL(LISTF) TCELL=TAGS(KK) Q=PTYPE<<16!LEVEL<<8!RBASE<<4!J ! ABORT %UNLESS (KFORM!ACC)>>16=0 QQQ=SLINK<<16!KFORM QQ=SNDISP<<16!ACC IF FROM1(TCELL)>>8&63=LEVEL THEN START FAULT(7,KK) Q=FROM1(TCELL)&X'C000'!Q;! COPY USED BITS ACCROSS REPLACE123(TCELL,Q,QQ,QQQ) FINISH ELSE START 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 QQQ RECORDNAME LCELL(LISTF) TCELL=TAGS(KK) IF TCELL=0 THEN START; ! NAME NOT SET TYPE=7; PTYPE=X'57'; PREC=5 ROUT=0; NAM=0; ARR=0; LITL=0; ACC=4 I=-1; J=-1; K=-1; OLDI=-1 FINISH ELSE START LCELL==ASLIST(TCELL) KK=LCELL_S1 LCELL_S1=KK!X'8000' MIDCELL=LCELL_S2 QQQ=LCELL_S3 PTYPE=KK>>16; USEBITS=KK>>14&3 OLDI=KK>>8&63; I=KK>>4&15; J=KK&15 SNDISP=MIDCELL&X'FFFF0000'//X'10000' ACC=MIDCELL&X'FFFF' K=QQQ>>16 KFORM=QQQ&X'FFFF' LITL=PTYPE>>14 ROUT=PTYPE>>12&3 NAM=PTYPE>>10&3 ARR=PTYPE>>8&3 PREC=PTYPE>>4&15 TYPE=PTYPE&15 FINISH END ROUTINE REDUCE TAG !*********************************************************************** !* AS COPY TAG FOR NAME AT A(P) EXCEPT:- * !* 1) SPECIAL NAMES HAVE THEIR CORRECT PREC & TYPE SUBSTITUTED * !* 2) RECORD ELEMENTS HAVE THE SUBNAME PARTICULARS RETURNED * !*********************************************************************** INTEGER SUBS,QQ,PP COPY TAG(FROMAR2(P)) IF PTYPE=SNPT THEN START PTYPE=TSNAME(K); UNPACK ROUT=1 FINISH; ! TO AVOID CHECKING PARAMS IF TYPE=3 THEN START PP=P; QQ=COPY RECORD TAG(SUBS); P=PP FINISH END ROUTINE REPLACE TAG(INTEGER KK) INTEGER P, Q P=TAGS(KK) Q=PTYPE<<16!USEBITS<<14!OLDI<<8!I<<4!J REPLACE 1(P, Q) REPLACE3(P, K<<16!KFORM) END ! LAYOUT OF PTYPE ! ****** ** ***** ! PTYPE REQUIRES 16 BITS TO DEFINE A VARIABLE AND CAN BE REGARDED AS ! AS TWO BYTEINTEGERS:= ! UPPER ONE(UPTYPE):= LITL<<6!ROUT<<4!NAM<<2!ARR ! LOWER ONE(PTYPE) :=PREC<<4!TYPE ! OFTEN (EG IN EXPOP) ONLY THE LOWER PART IS REQUIRED AS FUNCTIONS ! ETC ARE PREFETCHED AND STACKED. ! LITL:= 1=CONST,2=EXTERNAL,3=EXTRINSIC(OR DYNAMIC), 0=NONE OF THESE ! ROUT:= 1 FOR ROUTINE OR FN OR MAP, =0 NONE OF THESE ! NAM := 2 FOR MAPS AND 'REFREFS',=1 FOR NAMES ,=0 DIRECTLY ADDRESSED ! ARR :=1 FOR ARRAYS =0 SCALARS ! PREC IS DESCRIPTOR SIZE CODE FOR EACH PRECISION:- ! :=0 BITS,=3 BYTES, =5 WORDS, =6 D-WRDS, =7,QUAD WRDS ! TYPE:= THE VARIABLE TYPE ! :=0 (TYPE GENERAL),=1 INTEGER, =2 REAL, =3 RECORD ! :=4 (RECORDFORMAT),=5 STRING, =6 LABEL/SWITCH. =7 NOT SET ! ROUTINE UNPACK LITL=PTYPE>>14 ROUT=PTYPE>>12&3 NAM=PTYPE>>10&3 ARR=PTYPE>>8&3 PREC=PTYPE>>4&15 TYPE=PTYPE&15 END ROUTINE PACK(INTEGERNAME PTYPE) PTYPE=((((LITL<<2!ROUT)<<2!NAM)<<2!ARR)<<4!PREC)<<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, J RECORDNAME LCELL(LISTF) IF MASK=0 THEN CODE=JLK ELSE CODE=CALL IF MASK>0 THEN CODE=JCC IF MASK>=16 THEN CODE=JAT IF MASK>=32 THEN CODE=JAF VAL=PLABS(N) IF MASK<=0 THEN INSTRN=CODE<<24!3<<23 ELSE C INSTRN=CODE<<24!(MASK&15)<<21 IF VAL>0 THEN INSTRN=INSTRN!((VAL-CA)//2)&X'3FFFF' ELSESTART LCELL==ASLIST(PLINK(N)) J=INSTRN!CA; ! ONLY 18 BITS NEEDED FOR CA IF LCELL_S3#0 THEN PUSH(PLINK(N),J,0,0) ELSE START IF LCELL_S2=0 THEN LCELL_S2=J ELSE LCELL_S3=J FINISH FINISH PCONST(INSTRN) FORGET(-1) IF MASK<=0 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 GRINF1(WHICH)=INF THEN C GRAT(WHICH)=CA AND RESULT=WHICH OFFSET=PTR OFFSET(RLEV) PSF1(LDCODE(WHICH),1,OFFSET) GRUSE(WHICH)=USE; GRINF1(WHICH)=INF; GRAT(WHICH)=CA RESULT=WHICH END INTEGERFN XORYNB(INTEGER USE,INF) !*********************************************************************** !* CHECKS IF XNB OR YNB SET UP. IF NOT DECIDES WHICH TO OVERWRITE * !*********************************************************************** IF GRUSE(XNB)=USE AND GRINF1(XNB)=INF THEN GRAT(XNB)=CA C AND RESULT=XNB IF GRUSE(CTB)=USE AND GRINF1(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 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=RBASE THEN AREA=LNB AND RESULT=LNB; ! LOCAL LEVEL AREA=SET XORYNB(-1,BASE) FINISH RESULT=AREA END INTEGERFN AREA CODE2(INTEGER BS) !*********************************************************************** !* A VERSION OF AREA CODE WITHOUT SIDE EFFECTS ! * !*********************************************************************** IF BS=RBASE THEN RESULT=LNB RESULT=SET XORYNB(-1,BS) 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 SIZE=1 IF SIZE=0; ! BITS ABD BYTES! ! ABORT %UNLESS REG=ACCR %OR(REG=DR %AND SIZE=2) %OR %C (REG=BREG %AND SIZE=1) IF REG=DR THEN OPCODE=LD ELSE START IF REG=BREG THEN OPCODE=LB ELSE OPCODE=LSS+SIZE&6 FINISH ! IF REGISTER(REG)>=1 THEN START IF REGISTER(REG)=2 OR(ACCESS=2 AND AREA=0)THEN C BOOT OUT(REG) ELSE START; ! CANNOT SLSS ISN ON ALL MCS 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 AND 0#AREA#7 THEN GRUSE(DR)=0 GRUSE(REG)=0 END ROUTINE NOTE ASSMENT(INTEGER REG, ASSOP, VAR) !*********************************************************************** !* NOTES THE ASSIGNMENT TO SCALAR 'VAR'. THIS INVOLVES REMOVING * !* OLD COPIES FROM REGISTERS TO AVOID CONFUSING OLD AND NEW VALUE* !* ASSOP =1 FOR'==',=2 FOR '=',=3 FOR '<-' * !*********************************************************************** CONSTINTEGER EEMASK=B'100011110000000'; ! MASK OF USES RELEVANT TO == CONSTINTEGER EMASK=B'100011000000000'; ! MASK OF USES RELEVANT TO = CONSTINTEGER NREGS=5 CONSTINTEGER REGS=16*16*16*16*CTB+16*16*16*XNB+16*16*ACCR+16*BREG+DR INTEGER I,USE1,USE2,II RETURN IF VAR<=0 IF ASSOP=1 THEN START CYCLE I=0,1,7 USE1=GRUSE(I); USE2=USE1>>16; USE1=USE1&255 IF EEMASK&1<<USE2#0 AND (GRINF2(I)&X'FFFF'=VAR OR C GRINF2(I)>>16=VAR) THEN GRUSE(I)=USE1 AND USE2=0 IF EEMASK&1<<USE1#0 AND (GRINF1(I)&X'FFFF'=VAR OR C GRINF1(I)>>16=VAR) THEN GRUSE(I)=USE2 AND C GRINF1(I)=GRINF2(I) REPEAT GRUSE(REG)=7 GRINF1(REG)=VAR FINISH ELSE START CYCLE II=0,4,4*(NREGS-1) I=REGS>>II&15 USE1=GRUSE(I); USE2=USE1>>16; USE1=USE1&255 IF EMASK&1<<USE2#0 AND (GRINF2(I)&X'FFFF'=VAR OR C GRINF2(I)>>16=VAR OR GRINF2(I)=VAR) THEN C GRUSE(I)=USE1 AND USE2=0 IF EMASK&1<<USE1#0 AND (GRINF1(I)&X'FFFF'=VAR OR C GRINF1(I)>>16=VAR OR GRINF1(I)=VAR) THEN C GRUSE(I)=USE2 AND GRINF1(I)=GRINF2(I) ! ! ALL THE FOREGOING CONDITIONS ARE NOT AS SILLY AS THEY SEEM. MUST ! BEAR IN MIND THAT BOTH GRINF&VAR MAY BE RECORD ELEMENTS DEFINED ! BY ALL 32 BITS OF INF AS WELL AS MODIFIED SCALARS WHEN THE NAME ! ONLY TAKES 16 BITS ! REPEAT IF ASSOP=2 AND VAR>0 START USE1=GRUSE(REG) IF 5<=USE1&255<=6 START; ! ASSIGN CONST TO VAR GRUSE(REG)=USE1&255!(9<<16) GRINF2(REG)=VAR FINISH ELSE START; ! ASSIGN VAR OR EXP TO VAR GRUSE(REG)=USE1<<16!9 GRINF2(REG)=GRINF1(REG); ! PREVIOUS USE BECOMES 2NDRY GRINF1(REG)=VAR FINISH FINISH FINISH END END; ! OF ROUTINE CSS !*DELSTART ROUTINE PRINTUSE !*********************************************************************** !* UP TO TWO USES ARE REMEMBERED INFO IN GRINF1 & GRINF2 * !* BOTTOM HALF OF GRUSE RELATES TO INF1 TOP HALF TO INF2 * !* THE MEANS CLEARING GRUSE TO FORGETS THE REG COMPLETELY * !* ARRAY REGISTER KEEPS THE CLAIM STATUS AND GRAT THE LAST USE * !*********************************************************************** CONSTSTRING(3)ARRAY REGS(0:7)="ACC"," DR","LNB","XNB", " PC","CTB","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 ", " NAME+CNST "," AUXSTPTR- ", " BYTE DES "," HALF DES ", " VMY RES "," REC HDES "; CONSTSTRING(11)ARRAY STATE(-1:3)=C " LOCKED "," FREE ", " I-RESULT "," TEMPORARY ", " RT-PARAM "; ROUTINESPEC OUT(INTEGER USE,INF) INTEGER I,USE,INF CYCLE I=0,1,7 IF REGISTER(I)!GRUSE(I)#0 START USE=GRUSE(I) PRINTSTRING(REGS(I).STATE(REGISTER(I))) OUT(USE&255,GRINF1(I)) IF USE>>16#0 THEN PRINTSTRING(" ALSO ") C AND OUT(USE>>16,GRINF2(I)) NEWLINE FINISH REPEAT RETURN ROUTINE OUT(INTEGER USE,INF) CONSTINTEGER LNMASK=B'1100011110000000' CONSTINTEGER UNMASK=B'0100001110000000' PRINTSTRING(" USE = ".USES(USE)) IF LNMASK&1<<USE#0 THEN PRINTSTRING(PRINTNAME(INF&X'FFFF')) C ELSE WRITE(INF,1) IF USE=10 THEN PRINTSYMBOL('+') AND WRITE(INF>>16,1) IF UNMASK&1<<USE#0 AND INF>>16#0 THEN PRINTSTRING(" MODBY") C AND PRINTSTRING(PRINTNAME(INF>>16)) END END !*DELEND ROUTINE ABORT PRINTSTRING(" **************** ABORT******************** ABORT *******") !*DELSTART NCODE(ADDR(CODE(0)), ADDR(CODE(PPCURR)), CABUF) C UNLESS CA=CABUF PRINT USE !*DELEND MONITOR STOP END ROUTINE EPILOGUE !*********************************************************************** !* PLANT ANY SUBROUINES THAT HAVE BEEN REQUIRED DURING * !* THE CODE GENERATION PHASE * !*********************************************************************** INTEGER D,J ROUTINESPEC FILL(INTEGER LAB) IF PLINK(15)=0 THEN ->P16 ABORT P16: ! ! STRING RESOLUTION SUBROUTINE ! THIS IS ENTERED VIA A CALL INSTRN AND HAS 3 PARAMETERS ! P1(LNB+5) = RESD A CURRENT LENGTH DESCRIPTOR POINTING AT THE FIRST BYTE ! OF THE STRING BEING RESOLVED ! P2(LNB+7) = STD A MAX LENGTH DESCRIPTOR TO THE STRING IN WHICH ANY ! FRAGMENT IS TO BE STORED ! P3(LNB+9) - EXPD A CURRENT LENGTH DESCRIPTOR POINTING AT THE ! LENGTH BYTE OF STRING TO BE SEARCHED FOR ! ! IF RESOLUTION IS SUCCESSFULL CC IS SET TO 0 AND AN UPDATED VERSION ! OF RESD IS RETURNED IN THE ACC IN CASE THERE ARE FURTHER RESLNS ! ! CODE IS AS FOLLOWS:- ! ! LXN (LNB+0) OLD LNB ! LD (XNB+3) PLT DESCRIPTOR ! LDB 0 ZERO BOUND FOR MDIAG ! STD (LNB+3) STANDARD PLACE ! ASF 4 GRAB 2 TEMPORARIES ! LD (LNB+5) RESULT IF NULL ROUTE TAKEN ! SLD (LNB+9) EXPD ! LB 0 ! JAT 11,LNULL JUMP IF EXP NULL ! INCA 1 TO FIRST CHAR ! LB @DR FIRST CHAR INTO B ! STD (LNB+11) TEMP1 ! LSS (LNB+5) TYPE&BND OF RESD ! AND XIFF ! JAT 4,RESFAIL RESD IS NULL &EXPD NOT NULL ! LD (LNB+5) RESD TO DR !AGN SWNE L=DR SEARCH FOR FIRST CHAR ! JCC 8,RESFAIL NOT FOUND ! STD (LNB+13) SAVE IN TEMP 2 ! CYD 0 ! LD (LNB+11) EXP DESCRIPTOR FOR COMPARISON ! CPS L=DR,FILLER=FF CHECK REST OF EXPRSN ! JCC 8,L2 RESLN HAS SUCCEEDED ! LD (LNB+13) RESUME SCANNING ! SWEQ L=1 ADVANCE BY 1 AVOIDING MODD ! J AGN ! ! RESOLUTION COMPLETE. ARRANGE TO STORE FRAGMENT WITHOUT ANY FILLER CHARS ! SO S->S.(T).Z WORKS OK AND ALLOWING STD TO BE NULL ! !L2 SLSS (LNB+5) STORE UPDATED DES & GET BND ! ISB (LNB+13) GIVE LENGTH OF FRAGMENT ! ST B ! LSS (LNB+7) LENGTH OF STD ! JAF 4,*+6 ! ZERO FOR NO 1ST PART RESLN ! LSS 1 ! AND X1FF ! ICP B ! JCC 12,RESFAIL !LNULL LD (LNB+7) STD TO DR ! JAT 11,L3 STD NULL DONT SET LENGTH ! LSD (LNB+5) ORIGINIAL STRING ! MVL L=1 SET LENGTH BYTE FROM B ! LDB B TO STORE CHARS ! MV L=DR,FILLER=X'80' ASSIGN !L3 LD TOS RESULT AND SET CC=0 ! CYD 0 ! EXIT !RESFAIL MPSR X'24' SET CC=1 ! EXIT IF PLINK(16)=0 THEN ->P17 FILL(16) PSF1(LXN,1,0) PF1(LD,0,XNB,12) PSF1(LDB,0,0) PSF1(STD,1,12) PSF1(ASF,0,4) PSF1(LD,1,20) PSF1(SLD,1,36) PSF1(LB,0,0) PF3(JAT,11,0,X'24') PSF1(INCA,0,1) PF1(LB,2,7,0) PSF1(STD,1,44) PSF1(LSS,1,20) PF1(AND,0,0,X'1FF') PF3(JAT,4,0,X'27') PSF1(LD,1,23) PF2(SWNE,1,0,0,0,0) PF3(JCC,8,0,X'23') PSF1(STD,1,52) PSF1(CYD,0,0) PSF1(LD,1,44) PF2(CPS,1,1,0,0,X'FF') PF3(JCC,8,0,5) PSF1(LD,1,52) PF2(SWEQ,0,0,0,0,0) PSF1(JUNC,0,-12) PSF1(SLSS,1,20) PSF1(ISB,1,52) PF1(ST,0,BREG,0) PSF1(LSS,1,28) PF3(JAF,4,0,3) PSF1(LSS,0,1) PF1(AND,0,0,X'1FF') PF1(ICP,0,BREG,0) PF3(JCC,12,0,13) PSF1(LD,1,28) PF3(JAT,11,0,7) PSF1(LSD,1,20) PF2(MVL,0,0,0,0,0) PF1(LDB,0,BREG,0) PF2(MV,1,1,0,0,UNASSPAT&255) PF1(LD,0,TOS,0) PSF1(CYD,0,0) PSF1(EXIT,0,-X'40') PSF1(MPSR,0,X'24') PSF1(EXIT,0,-X'40') P17: ! ! 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 NEGATAIVE ! 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(17)=0 THEN ->P18 FILL(17) 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'35') PF3(JAF,0,0,7) PF1(SLSD,0,TOS,0) PF3(JAF,1,0,X'30') 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) 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) PF1(CALL,2,XNB,EXPEPDISP) PF1(JUNC,0,TOS,0) PF1(JUNC,0,0,(PLABS(7)-CA)//2) P18: ! ! MAPPED STRING ASSIGNMENT CHECK. CHECKING MODE ONLY. MUST MOVE ONLY ! CURRENT LENGTH INTO MAPPED STRINGS BUT MUST NOT OMIT THE CAPACITY ! CHECK. ACC & DR SET FOR MV ! ! ST TOS SAVE ACC DESRPTR ! AND X'1FF00000000' GET CURRENT LENGTH ! STUH B INTO BREG ! LSD TOS RESTORE ACC ! STD TOS SAVE DR DESCRPTR ! SBB 1 ! JAF 13,*+3 ! MODD B PROVOKE FAILURE IF RELEVANT ! ADB 1 ! LD TOS ! LDB B BOUND=CURRENT L +1(FOR LBYTE) ! J TOS ! IF PLINK(18)=0 THEN ->P19 CNOP(0,8) D=CA PCONST(511) PCONST(0); ! XFF00000000 FILL(18) PF1(ST,0,TOS,0) PF1(AND,0,PC,D) PF1(STUH,0,BREG,0) PF1(LSD,0,TOS,0) PF1(STD,0,TOS,0) PSF1(SBB,0,1) PF3(JAF,13,0,3) PF1(MODD,0,BREG,0) PSF1(ADB,0,1) PF1(LD,0,TOS,0) PF1(LDB,0,BREG,0) PF1(JUNC,0,TOS,0) P19: ! CONCATENATION ONE ! COPY THE FIRST STRING INTO THE WORK AREA ! B HAS REL DISP OF THE WORK AREA FROM LNB ! DR HAS CURRENT LENGTH DESCRIPTOR OF FIRST STRING ! RESULT IS A CURRENT LENGTH DESCRIPTOR TO WORK AREA IN DR AND ACC ! ! STLN TOS ! ADB TOS ! LXN B XNB TO WORK AREA ! SLB @DR CURRENT LENGTH TO B ! STB (%XNB+2) INTO LENGTH BYTE OF WK AREA ! INCA 1 DR PAST LENGTH BYTE ! CYD 0 BECOMES SOURCE STRING ! LD =X'180000FF0000000C' ! INCA TOS DESCRIPTOR TO WK STRING ! STD (%XNB+0) STORED FOR LATER ! LDB B ADJUSTED SO NO FILLING ! MV L=DR THE MOVE ! LD (%XNB+0) SET UP DR WITH RESULT ! LDB B CURRENT LENGTH AS BOUND ! INCA -1 TO POINT AT LENGTH BYTE ! CYD 0 TO ACC AS WELL ! J TOS RETURN IF PLINK(19)!PLINK(20)=0 THEN ->P21 CNOP(0,8); ! DOUBLE WORD ALLIGN D=CA PCONST(X'180000FF'); PCONST(12) FILL(19) PF1(STLN,0,TOS,0) PF1(ADB,0,TOS,0) PF1(LXN,0,BREG,0) PF1(SLB,2,7,0) PF1(STB,0,XNB,8) PSF1(INCA,0,1) PSF1(CYD,0,0) PF1(LD,0,PC,D) PF1(INCA,0,TOS,0) PF1(STD,0,XNB,0) PF1(LDB,0,BREG,0) PF2(MV,1,0,0,0,0) PF1(LD,0,XNB,0) PF1(LDB,0,BREG,0) PSF1(INCA,0,-1) PSF1(CYD,0,0) PF1(JUNC,0,TOS,0) ! ! CONCATENATION TWO ! ADD THE SECOND AND SUBSEQUENT STRINGS TO THE FIRST ! PARAMETERS AND RESULTS AS CONCATENATION ONE ! ! STLN TOS ! ADB TOS ! LXN B XNB TO WORK AREA ! LB @DR CURRENT LENGTH TO B ! STB TOS KEEP FOR THE MOVE ! ADB (%XNB+2) ADD OLD LENGTH ! INCA 1 PAST LENGTH BYTE ! CYD 0 BECOMES SOURCE STRING ! LD (%XNB+0) GET DESCRIPTOR TO WK STRING ! MODD (%XNB+2) MOVE ON PAST FIRST STRING ! LDB TOS TO MOVE RIGHT AMOUNT ! MV L=DR ! STB (%XNB+2) UP DATE WK STRING LENGTH ! CPB 255 ! JCC 2,CAPACITY EXCEEDED ! LD (%XNB+0) SET UP DR WITH RESULT ! LDB B CURRENT LENGTH AS BOUND ! INCA -1 TO POINT AT LENGTH BYTE ! CYD 0 TO ACC AS WELL ! J TOS RETURN IF PLINK(20)=0 THEN ->P21 FILL(20) PF1(STLN,0,TOS,0) PF1(ADB,0,TOS,0) PF1(LXN,0,BREG,0) PF1(LB,2,7,0) PF1(STB,0,TOS,0) PF1(ADB,0,XNB,8) PSF1(INCA,0,1) PSF1(CYD,0,0) PF1(LD,0,XNB,0) PF1(MODD,0,XNB,8) PF1(LDB,0,TOS,0) PF2(MV,1,0,0,0,0) PF1(STB,0,XNB,8) PF1(CPB,0,0,255) PF3(JCC,2,0,(PLABS(9)-CA)//2) PF1(LD,0,XNB,0) PF1(LDB,0,BREG,0) PSF1(INCA,0,-1) PSF1(CYD,0,0) PF1(JUNC,0,TOS,0) P21: ! ! THE STOP SEQUENCE ! CALL %SYSTEMROUTINE STOP(NO PARAMETERS) ! !STOP1 PRCL 4 ! LXN (LNB+4) ! RALN 5 ! CALL ((XNB+STOPEPDISP)) ! **PLEASE DONT COME BACK** ! IF PLINK(21)=0 THEN ->P22 FILL(21) CXREF("S#STOP",PARMDYNAMIC,2,J) PSF1(PRCL,0,4) PSF1(LXN,1,16) PSF1(RALN,0,5) PF1(CALL,2,XNB,J) PF1(X'4E',0,0,X'B00B'); ! IDLE B00B P22: ! ! PRINTPROFILE ! IF PLINK(22)=0 THEN ->P23 FILL(22) CXREF("S#PPROFILE",PARMDYNAMIC,2,J) PSF1(PRCL,0,4) PSF1(LXN,1,16) PF1(LDRL,0,XNB,PARMPROF) PF1(STD,0,TOS,0) PSF1(RALN,0,7) PF1(CALL,2,XNB,J) PF1(JUNC,0,TOS,0) P23: RETURN ROUTINE FILL(INTEGER LAB) !*********************************************************************** !* FILL JUMPS TO THIS LAB WITH JUMP TO CURRENT ADDRESS * !*********************************************************************** INTEGER AT,INSTRN,I,J INTEGERARRAY A(0:2) WHILE PLINK(LAB)#0 CYCLE POP(PLINK(LAB),A(0),A(1),A(2)) CYCLE I=0,1,2 INSTRN=A(I) IF INSTRN#0 THEN START AT=INSTRN&X'3FFFF' INSTRN=INSTRN&X'FFC00000' INSTRN=INSTRN!(CA-AT)>>1 PLUG(1,AT,INSTRN,4) FINISH REPEAT REPEAT PLABS(LAB)=CA END END ROUTINE DUMP CONSTS !*********************************************************************** !* OUTPUT THE CONSTANT TABLE AND MAKE ANY RELEVANT RELOCATIONS * !*********************************************************************** ROUTINESPEC DOIT(INTEGER VAL) ROUTINESPEC FILL(INTEGER CREFHEAD) INTEGER I,J,K,DISP,SIZE,BASE BASE=0 SIZE=CONSTPTR-BASE IF SIZE<=0 THEN RETURN CNOP(0,8) UNLESS CA&7=0 CODE OUT LPUT(1,SIZE*4,CA,ADDR(CTABLE(BASE))) !*DELSTART IF DCOMP#0 START PRINTSTRING(" CONSTANT TABLE") I=BASE CYCLE NEWLINE PRHEX(CA+4*(I-BASE),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 FINISH !*DELEND ! FILL(CREFHEAD) SIZE=(SIZE+1)&(-2) CA=CA+4*SIZE CABUF=CA RETURN ROUTINE FILL(INTEGER CREFHEAD) DISP=(CA-4*BASE)//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 END 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,4); ! UPDATE THE GLA WORD FINISH END END END; ! OF SUBBLOCK CONTAINING PASS2 STRINGFN MESSAGE(INTEGER N) !*********************************************************************** !* OUTPUTS AN ERROR MESSAGE STORED IN A COMPRESSED FORMAT * !* 1 %REPEAT is not required * !* 2 Label & has already been set in this block * !* 4 Switch & has not been declared * !* 5 Switch name & in expression or assignment * !* 6 Switch label &(#) set a second time * !* 7 Name & has already been declared * !* 8 Routine or fn & has more parameters than specified * !* 9 Parameter # of & differs in type from specification * !* 10 Routine or fn & has fewer parameters than specified * !* 11 Label & referenced at line # has not been set * !* 12 %CYCLE at line # has two control clauses * !* 13 %REPEAT for %CYCLE at line # is missing * !* 14 TOO MANY ENDS * !* 15 MISSING ENDS * !* 16 Name & has not been declared * !* 17 Name & does not require parameters or subscripts * !* 19 WRONG NO OF PARAMETERS * !* 20 # too few subscripts provided for array & * !* 21 # too many subscripts provided for array & * !* 22 ACTUAL PARAMETERS NOT AS SPEC * !* 23 ROUTINE NAME IN EXPRSSN * !* 24 REAL IN INTEGER EXPRSSN * !* 26 # is not a valid %EVENT number * !* 27 & is not a routine name * !* 28 Routine or fn & has specification but no body * !* 29 LHS NOT DESTNTN * !* 30 %RETURN outwith routine body * !* 31 %RESULT outwith fn or map body * !* 32 INVALID ASSEMBLER * !* 33 INVALID NAME IN ASSEMBLER * !* 34 TOO MANY LEVELS * !* 37 TOO MANY DIMENSIONS * !* 38 Array & has upper bound # less than lower bound * !* 40 DECLN MISPLACED * !* 41 Constant cannot be evaluated at compile time * !* 44 ILLEGAL CONST * !* 45 WRONG NO OF CONST * !* 46 & is declared as invalid type %EXTRINSIC %NAME * !* 47 %ELSE already given at line # * !* 48 %ELSE invalid after %ON %EVENT * !* 49 Attempt to initialise %EXTRINSIC or %FORMAT & * !* 50 Subscript of # is outwith the bounds of & * !* 51 %FINISH is not required * !* 52 %REPEAT instead of %FINISH for %START at line # * !* 53 %FINISH for %START at line # is missing * !* 54 %EXIT outwith %CYCLE %REPEAT body * !* 55 %CONTINUE outwith %CYCLE %REPEAT body * !* 56 ENDOFFILE OUT OF CONTEXT * !* 57 BEGIN MISSING * !* 58 CONTROL STMNT MISPLACED * !* 59 %FINISH instead of %REPEAT for %CYCLE at line # * !* 61 Name & has already been used in this %FORMAT * !* 62 NOT FORMAT NAME * !* 63 RECORD SPEC ERROR * !* 64 SUBNAME MISSING * !* 65 SUBNAME NOT IN FORMAT * !* 66 Expression assigned to record & * !* 67 Records && and & have different formats * !* 69 SUBNAME OUT OF CONTEXT * !* 70 ILLEGAL STRING DECLN * !* 71 & is not a String varaible * !* 72 Arithmetic operator in a String expression * !* 73 Arithmetic constant in a String expression * !* 74 Resolution is not the correct format * !* 75 String expression contains a sub expression * !* 76 String variable & in arithmetic expression * !* 77 String constant in arithmetic expression * !* 78 String operator '.' in arithmetic expression * !* 80 Pointer variable & compared with expression * !* 81 Pointer variable & equivalenced to expression * !* 82 & is not a pointer name * !* 83 && and & are not equivalent in type * !* 84 RECORD OUT OF CONTEXT * !* 86 Global pointer && equivalenced to local & * !* 90 Untyped name & used as variable * !* 91 %FOR control variable & not integer * !* 92 %FOR clause has zero step * !* 93 %FOR clause has noninteger number of traverses * !* 101 SOURCE LINE TOO LONG * !* 102 WORKFILE TOO SMALL * !* 103 NAMES TOO LONG * !* 104 TOO MANY NAMES * !* 105 TOO MANY LEVELS * !* 106 STRING CONST TOO LONG * !* 107 COMPILER TABLES FULL * !* 202 Name & not used * !* 203 Label & not used * !* 204 Global %FOR control variable & * !* 205 Name & not addressable * !* 255 SEE IMP MANUAL * !*********************************************************************** CONSTBYTEINTEGERARRAY OUTTT(0:63)='?','A','B','C','D','E','F','G', 'H','I','J','K','L','M','N', 'O','P','Q','R','S','T','U', 'V','W','X','Y','Z','&','-', '/','''','(',')', 'a','b','c','d','e','f','g', 'h','i','j','k','l','m','n', 'o','p','q','r','s','t','u', 'v','w','x','y','z','.','%', '#','?'(2) CONSTINTEGER WORDMAX= 584,DEFAULT= 580 CONSTHALFINTEGERARRAY WORD(0:WORDMAX)=0,C 1, 32769, 32771, 32772, 32773, 2, 32775, 32776, 32777, 32778, 32780, 32781, 32782, 32783, 32784, 4, 32785, 32776, 32777, 32772, 32780, 32787, 5, 32785, 32789, 32776, 32782, 32790, 32792, 32793, 6, 32785, 32795, 32796, 32781, 32797, 32798, 32800, 7, 32801, 32776, 32777, 32778, 32780, 32787, 8, 32802, 32792, 32804, 32776, 32777, 32805, 32806, 32808, 32809, 9, 32811, 32813, 32814, 32776, 32815, 32782, 32817, 32818, 32819, 10, 32802, 32792, 32804, 32776, 32777, 32822, 32806, 32808, 32809, 11, 32775, 32776, 32823, 32825, 32826, 32813, 32777, 32772, 32780, 32781, 12, 32827, 32825, 32826, 32813, 32777, 32829, 32830, 32832, 13, 32769, 32834, 32827, 32825, 32826, 32813, 32771, 32835, 14, 32837, 32838, 32839, 15, 32840, 32839, 16, 32801, 32776, 32777, 32772, 32780, 32787, 17, 32801, 32776, 32842, 32772, 32843, 32806, 32792, 32845, 19, 32847, 32848, 32849, 32850, 20, 32813, 32852, 32853, 32845, 32854, 32834, 32856, 32776, 21, 32813, 32852, 32857, 32845, 32854, 32834, 32856, 32776, 22, 32858, 32850, 32860, 32861, 32862, 23, 32863, 32865, 32866, 32867, 24, 32869, 32866, 32870, 32867, 26, 32813, 32771, 32772, 32797, 32872, 32873, 32875, 27, 32776, 32771, 32772, 32797, 32877, 32789, 28, 32802, 32792, 32804, 32776, 32777, 32819, 32879, 32880, 32881, 29, 32882, 32860, 32883, 30, 32885, 32887, 32877, 32881, 31, 32889, 32887, 32804, 32792, 32891, 32881, 32, 32892, 32894, 33, 32892, 32865, 32866, 32894, 34, 32837, 32838, 32896, 37, 32837, 32838, 32898, 38, 32900, 32776, 32777, 32901, 32902, 32813, 32903, 32808, 32904, 32902, 40, 32905, 32906, 41, 32908, 32910, 32912, 32913, 32825, 32915, 32800, 44, 32917, 32919, 45, 32847, 32848, 32849, 32919, 46, 32776, 32771, 32787, 32920, 32921, 32817, 32923, 32925, 47, 32926, 32778, 32927, 32825, 32826, 32813, 48, 32926, 32921, 32928, 32929, 32873, 49, 32930, 32932, 32933, 32923, 32792, 32935, 32776, 50, 32937, 32814, 32813, 32771, 32887, 32939, 32940, 32814, 32776, 51, 32942, 32771, 32772, 32773, 52, 32769, 32944, 32814, 32942, 32834, 32946, 32825, 32826, 32813, 53, 32942, 32834, 32946, 32825, 32826, 32813, 32771, 32835, 54, 32948, 32887, 32827, 32769, 32881, 55, 32949, 32887, 32827, 32769, 32881, 56, 32951, 32953, 32849, 32954, 57, 32956, 32840, 58, 32957, 32959, 32906, 59, 32942, 32944, 32814, 32769, 32834, 32827, 32825, 32826, 32813, 61, 32801, 32776, 32777, 32778, 32780, 32960, 32782, 32783, 32935, 62, 32860, 32961, 32865, 63, 32963, 32862, 32965, 64, 32966, 32840, 65, 32966, 32860, 32866, 32961, 66, 32968, 32970, 32932, 32972, 32776, 67, 32974, 32976, 32977, 32776, 32978, 32979, 32981, 69, 32966, 32953, 32849, 32954, 70, 32917, 32983, 32905, 71, 32776, 32771, 32772, 32797, 32985, 32987, 72, 32989, 32991, 32782, 32797, 32985, 32790, 73, 32989, 32993, 32782, 32797, 32985, 32790, 74, 32995, 32771, 32772, 32939, 32997, 32999, 75, 32985, 32790, 33001, 32797, 33003, 32790, 76, 32985, 33004, 32776, 32782, 33006, 32790, 77, 32985, 32993, 32782, 33006, 32790, 78, 32985, 32991, 33008, 32782, 33006, 32790, 80, 33009, 33004, 32776, 33011, 33013, 32790, 81, 33009, 33004, 32776, 33014, 32932, 32790, 82, 32776, 32771, 32772, 32797, 33017, 32789, 83, 32976, 32977, 32776, 33019, 32772, 33020, 32782, 32817, 84, 32963, 32953, 32849, 32954, 86, 33022, 33017, 32976, 33014, 32932, 33024, 32776, 91, 33025, 32830, 33004, 32776, 32772, 33026, 92, 33025, 33028, 32777, 33030, 33031, 93, 33025, 33028, 32777, 33032, 32875, 32814, 33034, 90, 33036, 32789, 32776, 32960, 32920, 33004, 8, 33038, 101, 33041, 33043, 32837, 33044, 102, 33045, 32837, 33047, 103, 33048, 32837, 33044, 104, 32837, 32838, 33048, 105, 32837, 32838, 32896, 106, 32983, 32919, 32837, 33044, 107, 33049, 33051, 33053, 202, 32801, 32776, 32772, 32960, 203, 32775, 32776, 32772, 32960, 204, 33022, 33025, 32830, 33004, 32776, 205, 32801, 32776, 32772, 33054, 255, 33057, 33058, 33059, 0 CONSTINTEGERARRAY LETT(0: 292)=0,C X'7890A80B',X'02A00000',X'53980000',X'5D7E8000', X'652E3AD3',X'652C8000',X'190C52D8',X'36000000', X'510E6000',X'436652C3',X'49C80000',X'452CB700', X'672E8000',X'53700000',X'69453980',X'4565F1D6', X'27BD3A47',X'50000000',X'492C7643',X'652C8000', X'5D0DB280',X'4BC6194B',X'679D37DC',X'5F900000', X'439E74CF',X'5D6CB768',X'590C52D8',X'36FFB000', X'42000000',X'672C77DD',X'48000000',X'694DB280', X'1D0DB280',X'257EBA53',X'5D280000',X'4D700000', X'5B7E5280',X'610E50DB',X'4BA4B966',X'69443700', X'6784B1D3',X'4D4CB200',X'210E50DB',X'4BA4B900', X'7A000000',X'5F300000',X'494CD34B',X'65980000', X'69CE1280',X'4D95F680',X'6784B1D3',X'4D4C70E9', X'537DC000',X'4D2EF2E4',X'652CD2E5',X'4B7472C8', X'43A00000',X'594DD280',X'781B2199',X'0A000000', X'69BDE000',X'477DDA65',X'5F600000',X'47643AE7', X'4B980000',X'4D7E4000',X'5B4E79D3',X'5D380000', X'2879E000',X'1A09CC80',X'0A708980',X'1A4A6993', X'1C380000',X'497CB980',X'652E3AD3',X'65280000', X'67AC59C7',X'654E1A66',X'2E91E70E',X'1C780000', X'1E300000',X'200A409B',X'0AA0A926',X'697DE000', X'4D2EE000',X'6195FB53',X'492C8000',X'439650F2', X'5B0DDC80',X'021A8A83',X'18000000',X'1C7A8000', X'02980000',X'2680A180',X'247AAA13',X'1C280000', X'1C09A280',X'12700000',X'0AC20927',X'26700000', X'24282600',X'1272828F',X'0A900000',X'6D0D94C8', X'782AC29D',X'28000000',X'5DADB14B',X'64000000', X'657EBA53',X'5D280000',X'45AE8000',X'5D780000', X'457C9C80',X'18426000',X'082A6A1D',X'28700000', X'7890AA2B',X'24700000',X'5FAE9BD3',X'69400000', X'7890A9AB',X'18A00000',X'5B0E0000',X'1272C099', X'12200000',X'029A629B',X'0460A900',X'182AC299', X'26000000',X'0849A29D',X'2649E726',X'039650F2', X'6B8612E4',X'457EB748',X'592E7980',X'597EF2E4', X'0828661C',X'1A4A6819',X'0218A200',X'077DD9E9', X'43768000',X'470DD75F',X'68000000',X'45280000', X'4BB4366B',X'43A4B200',X'477DB853',X'59280000', X'1261828F',X'02600000',X'0679C9A8',X'43980000', X'5376D0D9',X'53200000',X'782B0A25',X'12726486', X'7870268A',X'7829898A',X'4F4ED2DC',X'433692E4', X'7879C000',X'03A692DB',X'61A00000',X'69780000', X'53753A53',X'436539CA',X'7831E91B',X'02A00000', X'27AC59C7',X'654E1A00',X'6944A000',X'457EB749', X'66000000',X'78312713',X'26400000',X'53767A4B', X'43200000',X'789A80A5',X'28000000',X'782B04A8', X'7819E729',X'1272A280',X'0A70878D',X'0C498280', X'1EAA8000',X'0679CA0B',X'30A00000',X'0428E49C', X'0679CA25',X'1E600000',X'26A1A728',X'6B9CB200', X'0C7A4683',X'28000000',X'242867A5',X'08000000', X'0A9247A4',X'26A84703',X'1A280000',X'0BC6194B', X'679D37DC',X'439E74CF',X'5D2C8000',X'652C77E5', X'48000000',X'252C77E5',X'49980000',X'36D80000', X'43748000',X'510ED280',X'494CD34B',X'652DDA00', X'4D7E56C3',X'69980000',X'26A2449D',X'0E000000', X'27A654DD',X'4E000000',X'6D0E50D3',X'4564A000', X'03953A51',X'5B2E94C6',X'5F84B943',X'697E4000', X'477DD9E9',X'43768000',X'252E77D9',X'6BA537DC', X'477E594B',X'47A00000',X'4D7E56C3',X'68000000', X'477DDA43',X'53766000',X'67AC4000',X'6D0E54C3', X'4564A000',X'43953A51',X'5B2E94C6',X'3DDBC000', X'217D3769',X'4B900000',X'477DB843',X'652C8000', X'6F4E9400',X'4B8EB4ED',X'4364B747',X'4B200000', X'617D3769',X'4B900000',X'4394A000',X'4B8EB4ED', X'4364B768',X'0F65F143',X'58000000',X'597C70D8', X'7831E900',X'537692CF',X'4B900000',X'47643AE7', X'4A000000',X'752E5780',X'67A4B800',X'5D7DD4DD', X'692CF2E4',X'69943B4B',X'659CB980',X'2B769CE1', X'4B200000',X'0220890B',X'26982113',X'184A8C80', X'267AA907',X'0A000000',X'1849C280',X'1879C380', X'2E7A458D',X'1260A000',X'26682618',X'1C09A2A6', X'0679A813',X'182A4000',X'2808460B',X'26000000', X'0CA98600',X'4324994B',X'679C3159',X'4A000000', X'2628A000',X'126A0000',X'1A09CA83',X'18000000' INTEGER I,J,K,M,Q,S STRING(70)OMESS OMESS=" " CYCLE I=1,1,WORDMAX-1 ->FOUND IF N=WORD(I) REPEAT I=DEFAULT FOUND: J=1 CYCLE K=WORD(I+J) IF K&X'8000'=0 THEN EXIT K=K!!X'8000' OMESS=OMESS." " UNLESS J=1 UNTIL M&1=0 CYCLE M=LETT(K); S=25 UNTIL S<0 CYCLE Q=M>>S&63; IF Q¬=0 THEN OMESS=OMESS.TOSTRING(OUTTT(Q)) S=S-6 REPEAT K=K+1 REPEAT J=J+1 REPEAT RESULT=OMESS END STRING(16)FN SWRITE(INTEGER VALUE, PLACES) STRING (16) S INTEGER D0, D1, D2, D3, L PLACES=PLACES&15 *LSS_VALUE; *CDEC_0 *LD_S; *INCA_1; *STD_TOS *CPB_B; ! SET CC=0 *SUPK_L=15,0,32; ! UNPACK & SPACE FILL *STD_D2; *JCC_8,<WASZERO> *LD_TOS; *STD_D0; ! FOR SIGN INSERTION *LD_TOS *MVL_L=15,63,0; ! FORCE ISO ZONE CODES IF VALUE<0 THEN BYTEINTEGER(D1)='-' L=D3-D1 OUT: IF PLACES>=L THEN L=PLACES+1 D3=D3-L-1 BYTEINTEGER(D3)=L RESULT=STRING(D3) WASZERO: BYTEINTEGER(D3-1)='0' L=2; ->OUT END ROUTINE FAULT2(INTEGER N, DATA, IDENT) !*********************************************************************** !* SETS UP AN ERROR MESSAGE AND SHOVES IT OUT ONTO THE LISTING * !* AN ALSO OPTIONALLY TO THE TERMINAL * !*********************************************************************** INTEGER I, J, T STRING(255)MESS1,MESS2,WK1,WK2 !*DELSTART MONITOR IF FAULTY<=1 AND (SMAP#0 OR DCOMP#0) !*DELEND MESS1=""; MESS2="" FAULTY=FAULTY+1 IF N=100 THEN START; ! SYNTAX FAULTS ARE SPECIAL MESS1=" * Failed to analyse line ".SWRITE(LINE,2)." " IF LINE#OLDLINE THEN MESS1=MESS1.C "Text mode failure - erroneos source line not available " ELSE START J=0; S=0; T=0 UNTIL (J=';' AND Q>QMAX) OR Q=LENGTH CYCLE I=J; J=BYTEINTEGER(DATA+Q);! DATA HAS ADDR(CC(0)) IF J>128 AND I<128 THEN MESS2=MESS2." %" AND T=T+2 IF I>128 AND J<128 THEN MESS2=MESS2." " AND T=T+1 MESS2=MESS2.TOSTRING(J) T=T+1 IF Q=QMAX THEN S=T Q=Q+1 EXIT IF T>=250 REPEAT IF Q=QMAX THEN S=T FINISH FINISH ELSE START MESS1=" *".SWRITE(LINE, 4)." " PARMOPT=1 INHCODE=1 IF PARMLET=0; ! STOP GENERATING CODE MESS1=MESS1."FAULT".SWRITE(N,2) MESS2=MESSAGE(N) IF MESS2->WK1.("##").WK2 THEN C MESS2=WK1.SWRITE(IDENT,1).WK2 IF MESS2->WK1.("#").WK2 THEN C MESS2=WK1.SWRITE(DATA,1).WK2 IF MESS2->WK1.("&&").WK2 THEN C MESS2=WK1.PRINTNAME(DATA).WK2 IF MESS2->WK1.("&").WK2 THEN C MESS2=WK1.PRINTNAME(IDENT).WK2 IF N>100 THEN MESS2=MESS2." Disaster" FINISH CYCLE I=2,-1,1 SELECT OUTPUT(TTOPUT) IF I=1 PRINTSTRING(MESS1) PRINTSTRING(MESS2) IF MESS2#"" IF N=100 AND S<115 THEN START NEWLINE; SPACES(S+4); PRINTSYMBOL('!') FINISH NEWLINE SELECT OUTPUT(82) IF I=1 EXIT IF TTOPUT<=0 REPEAT IF N>100 THEN MONITOR AND STOP END ROUTINE FAULT(INTEGER N,FNAME) FAULT2(N,FNAME,FNAME) END ROUTINE WARN(INTEGER N,V) STRING(30) T; STRING(120) S S=MESSAGE(N+200) IF S->S.("&").T THEN S=S.PRINTNAME(V).T PRINTSTRING(" ? Warning :- ".S." at line No".SWRITE(LINE,1)) NEWLINE END ! THE NEXT 4 ROUTINES CAN BE !MACROISED USING MVC ! ROUTINE TOAR2(INTEGER PTR,VALUE) IF USE IMP=YES THEN START A(PTR+1)<-VALUE A(PTR)<-VALUE>>8 FINISH ELSE START *LSS_VALUE *LDTB_X'58000002' *LDA_A+4 *INCA_PTR *ST_(DR) FINISH END ROUTINE TOAR4(INTEGER PTR, VALUE) INTEGER I IF USE IMP=YES THEN START CYCLE I=0,1,3 A(PTR+I)=BYTE INTEGER(ADDR(VALUE)+I) REPEAT FINISH ELSE START *LSS_VALUE *LDTB_X'58000004' *LDA_A+4 *INCA_PTR *ST_(DR) FINISH END ROUTINE TOAR8(INTEGER PTR, LONGREAL VALUE) INTEGER I IF USE IMP=YES THEN START CYCLE I=0,1,7 A(PTR+I)=BYTE INTEGER(ADDR(VALUE)+I) REPEAT FINISH ELSE START *LSD_VALUE *LDTB_X'58000008' *LDA_A+4 *INCA_PTR *ST_(DR) FINISH END INTEGERFN FROMAR2(INTEGER PTR) IF USE IMP=YES THEN RESULT=A(PTR)<<8!A(PTR+1) ELSESTART *LDTB_X'58000002' *LDA_A+4 *INCA_PTR *LSS_(DR) *EXIT_-64 FINISH END INTEGERFN FROMAR4(INTEGER PTR) IF USE IMP=YES THEN START RESULT=A(PTR)<<24!A(PTR+1)<<16!A(PTR+2)<<8!A(PTR+3) FINISH ELSE START *LDTB_X'58000004' *LDA_A+4 *INCA_PTR *LSS_(DR) *EXIT_-64 FINISH END STRINGFN PRINTNAME(INTEGER N) INTEGER V, K STRING(255)S V=WORD(N) K=BYTE INTEGER(DICTBASE+V) IF K=0 THEN S="???" ELSE S=STRING(DICTBASE+V) RESULT=S END !*DELSTART 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 ROUTINE PRINT LIST(INTEGER HEAD) INTEGER I,J,K PRINTSTRING(" PRINT OF LIST ") WRITE(HEAD,2) NEWLINE WHILE HEAD#0 CYCLE FROM123(HEAD,I,J,K) WRITE(HEAD,3) SPACES(3) PRHEX(I,8) SPACES(3) PRHEX(J,8) SPACES(3) PRHEX(K,8) NEWLINE MLINK(HEAD) HEAD=HEAD&X'FFFF'; ! EXTRA LINK IN TAGS LIST!! REPEAT END ! ROUTINE CHECK ASL !*********************************************************************** !* CHECK ASL AND PRINT NO OF FREE CELLS. DEBUGGING SERVICE ONLY * !*********************************************************************** INTEGER N,Q Q=ASL; N=0 WHILE Q#0 CYCLE N=N+1 Q=ASLIST(Q)_LINK REPEAT NEWLINE PRINTSTRING("FREE CELLS AFTER LINE ") WRITE(LINE,3) PRINTSYMBOL('=') WRITE(N,3) END !*DELEND INTEGERFN MORE SPACE !*********************************************************************** !* FORMATS UP SOME MORE OF THE ASL * !*********************************************************************** INTEGER I,N,CL,AMOUNT N=ASL CUR BTM-1 AMOUNT=(NNAMES+1)>>3; ! EIGHTTH OF NNAMES I=ASL CUR BTM-((CONST PTR+8)>>2);! GAP BETWEEN CONSTS &ASL IF I>>1<AMOUNT THEN AMOUNT=I>>1 AND ASL WARN=1; ! HALF THE GAP MAX IF AMOUNT<20 THEN AMOUNT=0 ASL CUR BTM=ASL CUR BTM-AMOUNT IF ASL CUR BTM<=1 THEN ASL CUR BTM=1 CL=4*ASL CUR BTM-8 IF ASL CUR BTM>=N OR CONST PTR>CL THEN START ASL CUR BTM=N+1; ! AS YOU WERE CYCLE I=12,-1,1 IF DVHEADS(I)#0 THEN CLEAR LIST(DVHEADS(I)) REPEAT IF ASL#0 THEN RESULT=ASL FAULT(107,0) FINISH ELSE CONST LIMIT=CL; ! NEW VALUE WITH BIGGER ASL 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 !%INTEGERFN NEW CELL !*********************************************************************** !* PROVIDE A NEW LIST PROCESSING CELL. CRAPOUT IF NONE AVAILABLE * !*********************************************************************** !%INTEGER I ! %IF ASL=0 %THEN ASL=MORE SPACE ! I=ASL ! ASL=ASLIST(ASL)_LINK ! ASLIST(I)_LINK=0 ! %RESULT =I !%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 USE IMP=YES 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 USE IMP=YES 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 END: FINISH END ROUTINE REPLACE1(INTEGER CELL, S1) ASLIST(CELL)_S1=S1 END ROUTINE REPLACE2(INTEGER CELL, S2) ASLIST(CELL)_S2=S2 END ROUTINE REPLACE3(INTEGER CELL, S3) ASLIST(CELL)_S3=S3 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,J 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 INSERT AT END(INTEGERNAME CELL, INTEGER S1, S2, S3) !*********************************************************************** !* ADD A CELL TO THE BOTTOM OF THE LIST HEADED BY 'CELL' * !*********************************************************************** INTEGER I,J,N RECORDNAME LCELL(LISTF) I=CELL; J=I WHILE I#0 CYCLE J=I I=ASLIST(J)_LINK REPEAT N=ASL IF N=0 THEN N=MORE SPACE LCELL==ASLIST(N) ASL=LCELL_LINK IF J=0 THEN CELL=N ELSE ASLIST(J)_LINK=N LCELL_S1=S1 LCELL_S2=S2 LCELL_S3=S3 LCELL_LINK=0 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 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 FROM12(INTEGER CELL, INTEGERNAME S1, S2) RECORDNAME LCELL(LISTF) LCELL==ASLIST(CELL) S1=LCELL_S1 S2=LCELL_S2 END INTEGERFN FROM1(INTEGER CELL) RESULT =ASLIST(CELL)_S1 END INTEGERFN FROM2(INTEGER CELL) RESULT =ASLIST(CELL)_S2 END INTEGERFN FROM3(INTEGER CELL) RESULT =ASLIST(CELL)_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 CYCLE J=I I=ASLIST(J)_LINK REPEAT 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; ! AN ERROR PUTS CELL TWICE ONTO ! FREE LIST - CATASTROPHIC! ENDOFPROGRAM