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