%externalroutinespec debug(%string(255)s)

!   Computer Science IMP77 Compiler   -   Version 8  First pass
!                         23rd March 1981
!
%control 0

%external %string (15) %fn %spec date
%external %string (15) %fn %spec time

%externalintegerfn pass1(%integer object tank)
   %externalroutinespec put(%integer n)
   %externalroutinespec putword(%integer n)
   %externalroutinespec putlong(%integer n)
   %externalroutinespec putblock(%integer len, %bytename b)
   %externalroutinespec select output tank(%integer n)
   %systemroutinespec exit %alias "exit" (%integer status)
   %externalstring(63)%spec error message
   %externalstring(72)%fnspec sysmess(%integer n)
   %externalstring(127)%fnspec infilename

   %externalstring(6) version = "V08.02"

   %externalintegerspec command

   %constinteger warnbit = 8_200
   %constinteger listbit = 8_400

   !configuration parameters

   %CONSTINTEGER max int      = ((-1)>>1)//10
   %CONSTINTEGER max dig      = (-1)>>1-maxint*10
   %CONSTINTEGER byte size    = 8;            !bits per byte
   %CONSTINTEGER max tag      = 1200;          !max no. of tags
   %CONSTINTEGER max dict     = 9000;         !max extent of dictionary
   %CONSTINTEGER name bits    = 11
   %CONSTINTEGER max names    = 1<<namebits-1
   %OWNINTEGER   spare names  = max names
   %CONSTINTEGER max grammar  = 1800
   %CONSTINTEGER lit max      = 50;           !max no. of constants/stat.
   %CONSTINTEGER rec size     = 260;          !size of analysis record
   %CONSTINTEGER dim limit    = 6;            !maximum array dimension

   !symbols

   %CONSTINTEGER ff     = 12;              !form feed
   %CONSTINTEGER marker = '^';             !marker for faults
   %CONSTINTEGER squote = '"';             !string quote
   %CONSTINTEGER cquote = '''';            !character quote

   !streams

   %CONSTINTEGER   source = 1, prims = 2
   %CONSTINTEGER report = 0, listing = 2


   !types

   %CONSTINTEGER integer = 1
   %CONSTINTEGER real    = 2
   %CONSTINTEGER stringv = 3
   %CONSTINTEGER record  = 4

   !forms

   %CONSTINTEGER iform = integer<<4+1

   %CONSTINTEGER var = 91
   %CONSTINTEGER const   = 93
   %CONSTINTEGER swit    = 105
   %CONSTINTEGER comment = 22
   %CONSTINTEGER termin  = 20
   %CONSTINTEGER lab     = 3
   %CONSTINTEGER jump    = 54

   %CONSTINTEGER recfm = 4
   %CONSTINTEGER proc  = 7;                     !class for proc

   !phrase entries

   %CONSTINTEGER escdec   = 252
   %CONSTINTEGER escproc  = 253
   %CONSTINTEGER escarray = 254
   %CONSTINTEGER escrec   = 255

   %RECORDFORMAT arfm({GT:%SHORT}%INTEGER class,sub,link,ptype,papp,pformat,x,pos);!imp77:

   %RECORDFORMAT tagfm(%INTEGER app, format, %C
                       {GT:%SHORT}%INTEGER flags, index, text, link)

   !flags

!      *===.===.===.===.===.====.====.====.===.======.======*
!      ! u ! c ! c ! p ! s ! a  ! o  ! pr ! s ! type ! form !
!      ! 1 ! 1 ! 1 ! 1 ! 1 ! 1  ! 1  ! 1  ! 1 !  3   !  4   !
!      *===^===^===^===^===^====^====^====^===^======^======*
!        u   c   c   p   s   a    o    p    s    t      f
!        s   l   o   a   u   n    w    r    p    y      o
!        e   o   n   r   b   a    n    o    e    p      r
!        d   s   s   a   n   m         t    c    e      m
!            e   t   m   a   e
!            d       s   m
!                        e
!
!

   %CONSTINTEGER used bit   = 2_1000000000000000,
                 closed     = 2_0100000000000000,
                 const bit  = 2_0010000000000000,
                 parameters = 2_0001000000000000,
                 subname    = 2_0000100000000000,
                 aname      = 2_0000010000000000,
                 own bit    = 2_0000001000000000,
                 prot       = 2_0000000100000000,
                 spec       = 2_0000000010000000

   %CONSTINTEGER trans bit  = 16_4000
   %CONSTINTEGER error      = 16_8000

   %CONSTINTEGER manifest = 120, figurative = 130
   %CONSTINTEGER actions  = 180, phrasal    = 200

   %CONSTBYTEINTEGERARRAY amap(0:15) = %C
 89, 91, 92, 104, 94, const, swit, 100, 101, 102, 103, 106, 107, 108, 109, 89
!?   v   n   l    fm  const  swit  rp   fp   mp   pp   a    an   na   nan  ?

   %CONSTBYTEINTEGERARRAY atoms(0:15) = 89, 1, 1, 10,  9,  1, 10,  7,
                                         7, 7, 7,  4,  1,  4,  1, 89

   %RECORD(arfm)%ARRAY ar(1:rec size)

   %OWNINTEGER class = 0;                    !class of atom wanted
   %OWNINTEGER x = 0;                        !usually last tag
   %OWNINTEGER atom1 = 0;                    !atom class (major)
   %OWNINTEGER atom2 = 0;                    !atom class (minor)
   %OWNINTEGER subatom = 0;                  !extra info about atom
   %OWNINTEGER type = 0, app = 0, format = 0;!atom info
   %INTEGER hash value
   %OWNINTEGER faulty  = 0;                  !fault indicator
   %OWNINTEGER fault rate = 0;               !fault rate count
   %OWNINTEGER lines = 0;                    !current line number
   %OWNINTEGER text line = 0;                !starting line for string const
   %OWNINTEGER margin = 0;                   !statement start margin
   %OWNINTEGER error margin = 0, error sym = 0, column = 0
   %OWNINTEGER stats = 0;                    !statements compiled
   %OWNINTEGER mon pos = 0;                  !flag for diagnose
   %OWNINTEGER sym = nl;                     !current input symbol
   %OWNINTEGER symtype = 0;                  !type of current symbol
   %OWNINTEGER quote = 0;                    !>0 strings, <0 chars
   %owninteger end mark = 0;                  !%end flag
   %OWNINTEGER cont = ' ', csym = ' ';       !listing continuation marker
   %OWNINTEGER decl = 0;                     !current declarator flags
   %OWNINTEGER dim  = 0;                     !arrayname dimension
   %OWNINTEGER spec given = 0

   %OWNINTEGER escape class = 0;             !when and where to escape
   %OWNINTEGER protection=0, atom flags=0
   %OWNINTEGER otype = 0;                    !current 'own' type
   %OWNINTEGER reals ln = 1;                 ! =4 for %REALSLONG
   %OWNINTEGER last1 = 0;                    !previous atom class
   %OWNINTEGER gen type = 0
   %OWNINTEGER ptype = 0;                    !current phrase type
   %OWNINTEGER papp = 0;                     !current phrase parameters
   %OWNINTEGER pformat = 0;                  !current phrase format
   %OWNINTEGER force = 0;                    !force next ptype
   %OWNINTEGER g = 0, gg = 0, map gg = 0;            !grammar entries
   %OWNINTEGER fdef  = 0;                    !current format definition
   %OWNINTEGER this  = -1;                   !current recordformat tag
   %OWNINTEGER nmin = 0;                     !analysis record atom pointer
   %OWNINTEGER nmax = 0;                     !analysis record phrase pointer
   %OWNINTEGER rbase = 0;                    !record format definition base
   %OWNINTEGER stbase = 0;                   !constant work area base
   %OWNINTEGER gmin = max grammar;           !upper bound on grammar
   %OWNINTEGER dmax = 1
   %OWNINTEGER tmin = max tag;               !upper bound on tags
   %OWNINTEGER ss      = 0;                  !source statement entry
      %STRING(63) include file
   %OWNINTEGER include list = 0
   %OWNINTEGER include = 0;                  !=0 unused, #0 being used
   %OWNINTEGER perm    = 1;                  !1 = compiling perm, 0 = program
   %OWNINTEGER progmode= 0;                  !-1 = file, 1 = begin/eop
   %OWNINTEGER sstype = 0;                   !-1:exec stat
                                             ! 0: declaration
                                             ! 1: block in
                                             ! 2: block out
   %OWNINTEGER spec mode = 0;                !>=0: definition
                                             ! -1: proc spec
                                             ! -2: recordformat
   %OWNINTEGER ocount  = -1;                 !own constants wanted
   %OWNINTEGER limit   = 0;                  !lookup limit
   %OWNINTEGER copy    = 0;                  !duplicate name flag
   %OWNINTEGER order   = 0;                  !out of sequence flag
   %OWNINTEGER for warn = 0;                 !non-local flag
   %OWNINTEGER dubious = 0;                  !flag for dubious statements
   %OWNINTEGER dp      = 1
   %OWNINTEGER pos1    = 0, pos2 = 0;        !error position
   %OWNINTEGER pos     = 0;                  !input line index
   %OWNINTEGER dimension = 0;                !current array dimension
   %OWNINTEGER local = 0;                    !search limit for locals
   %OWNINTEGER fm base = 0;                  !entry for format decls
   %OWNINTEGER search base = 0;              !entry for record_names
   %OWNINTEGER format list = 0;              !size of current format list
   %INTEGER recid
   %ownbyteintegername current char
   %OWNBYTEINTEGERARRAY char(0:133)=nl(134);  !input line
   %INTEGERARRAY lit pool(0:lit max)
   %OWNINTEGER lit = 0;                      !current literal (integer)
   %OWNINTEGER lp = 0;                       !literals pointer
   %OWNINTEGER block x = 0;                  !block tag
   %OWNINTEGER list    = 2;                  !<= to enable
   %OWNINTEGER control = 0
   %OWNINTEGER diag = 0;                     !diagnose flags
   %SHORTINTEGERARRAY hash(0:max names)
   %RECORD(tagfm)%ARRAY tag(0:max tag)
   {GT:%SHORT}%INTEGERARRAY dict(1:max dict)

!*** start of generated tables ***
!!   %include "tables.imp"
!!   %endoflist
%conststring(8)%array text(0:255) = %c
"Z","VDEC","OWNVDEC","EXTVSPEC","ADEC","OWNADEC",
"EXTASPEC","PROC","PROCSPEC","FORMDEC","SWDEC","LDEC",
"FORMSPEC","","","","","",
"OPTION","COMMA","T","COLON","COMMENT","LB",
"ALIAS","RB","SUB","ARRAYD","STYPE","ARRAY",
"NAME","PROCD","FNMAP","SWITCH","OWN","EXTERNAL",
"STRING","RECORD","FORMAT","SPEC","MCODE","LABEL",
"OP1","OP2","OP3","SIGN","UOP","MOD",
"DOT","COMP","ACOMP","EQ","EQEQ","JAM",
"JUMP","RESOP","AND","OR","NOT","WHILE",
"UNTIL","FOR","CWORD","EXIT","ON","SIGNAL",
"THEN","START","ELSE","FINISH","FELSE","CYCLE",
"REPEAT","PROGRAM","BEGIN","END","ENDPROG","ENDPERM",
"FRESULT","MRESULT","BACK","MONITOR","STOP","LIST",
"","CONTROL","INCLUDE","MASS","RTYPE","ADDOP",
"IDENT","V","N","CONST","FM","",
"R","F","M","P","RP","FP",
"MP","PP","L","S","A","AN",
"NA","NAN","","","","",
"","","","","","",
"%MSTART","%CLEAR","%PRED","","%DUBIOUS","%DUP",
"%PIN","%POUT","%EDUP","","PIDENT","CIDENT",
"OIDENT","FNAME","SWID","DOTL","DOTR","ASEP",
"CSEP","OSEP","PSEP","ARB","BPLRB","ORB",
"PRB","CRB","RCRB","RECRB","RECLB","LAB",
"MLAB","SLAB","XNAME","OWNT","DBSEP","PCONST",
"CMOD","CSIGN","CUOP","COP1","COP2","COP3",
"INDEF","XELSE","CRESOP","NLAB","RUNTIL","ACONST",
"ORRB","FMANY","OSTRING","FMLB","FMRB","FMOR",
"RANGERB","FSID","","","","",
"","%DUMMY","%DECL","%TYPE","%ZERO","%APPLY",
"%PROT","%SETPROT","%PTYPE","%GAPP","%LOCAL","%GUARD",
"%MCODE","%CDUMMY","%SETTYPE","%OPER","%PARAM","%BLOCK",
"%OTHER","%COMPILE","APP","BASEAPP","APP2","APP3",
"APP4","APP5","APP6","ADEFN","NPARM","SWDEF",
"SWIDS","CIEXP","RCONST","SCONST","ARRAYP","XIMP",
"IMP","COND","SCOND","EXP1","EXP2","SEXP",
"IEXP","IEXP1","IEXP2","ISEXP","SEQ","FDEF",
"EXP","NARRAYP","STRUCT","RESEXP","BPL","CONSTB",
"FITEM","MOREA","CLIST","FPP","FPP0","FPP1",
"FPP2","INITVAR","RECEXP","EIMP","IDENTS","RANGE",
"RCONSTB","VARP","INITDEC","","","",
"ESCDEC","ESCPROC","ESCARRAY","ESCREC"
%constinteger gmax1=718
%owninteger gmax=718
%constinteger imp phrase =24

%ownshortintegerarray phrase(200:255) = %C
   0, 563, 564, 566, 568, 570, 572, 561,
 613, 202, 199, 601, 477, 479, 623, 297,
 205, 307, 317, 432, 425, 436, 443, 457,
 452, 460, 466, 481, 401, 626, 628, 602,
 520, 510, 485, 501, 574, 526, 527, 542,
 549, 577, 396, 286, 196, 635, 515, 620,
 166,   0,   0,   0, 639, 692, 700, 708

%constbyteintegerarray atomic(130:179) = %c
  90,  90,  90,  90,  90,  48,  48,  19,
  19,  19,  19,  25,  25,  25,  25,  25,
  25,  25,  23, 104, 104, 105,  30,  20,
  21,  93,  47,  45,  46,  42,  43,  44,
  40,  68,  55, 104,  60,  93,  25,  40,
  93,  23,  25,  57,  25,  90, 176, 177,
 178, 179

!  FLAG<1> 0<1> SS<2> 0<3> T<1> LINK<8>
%constshortintegerarray initial(0:119) = %c
      23,       0,       0,       0,       0,       0,       0,       0,
       0,       0,       0,       0,       0,       0,       0,       0,
       0,       0,      22,       0,       0,       0,       0,       0,
       0,       0,       0,       0,       0,       0,       0,       0,
       0,       0,       0,       0,       0,       0,       0,       0,
      20,       0,       0,       0,       0,       0,       0,       0,
       0,       0,       0,       0,       0,       0,  -32552,       0,
       0,       0,       0,      13,       0,      14,       4,  -32558,
      16,  -32551,       0,       0,       5,       6,       3,      12,
      15,       8,       7,       9,      10,      11,  -32559,  -32555,
  -32560,  -32553,  -32554,      18,       0,      17,      21,      19,
       0,       0,       0,  -32563,  -32561,       0,       0,       0,
  -32562,       0,       0,       0,       0,       0,       0,       0,
       1,       2,       0,  -32557,       0,  -32556,       0,       0,
       0,       0,       0,       0,       0,       0,       0,       0

!  MORE<1> 0<1> ORDER<2> TYPE<4> CLASS<8>
%ownshortintegerarray gram(0:max grammar) = %c
       0,  -28523,  -28521,  -28602,  -32706,  -28509,  -28603,  -24502,
  -24503,  -20405,  -20404,  -28595,  -32697,  -32709,  -16323,  -28600,
  -32704,  -28587,  -28589,  -32681,  -16344,  -28586,  -16366,  -32586,
     216,  -12287,  -16380,   -8185,   -8184,  -12285,  -12286,  -12283,
  -12282,  -12279,  -12276,  -16373,   20490,  -32706,  -32701,     216,
  -16364,  -28610,  -28613,  -28612,   16445,     217,  -16364,      62,
  -32701,   16450,  -16364,    5346,  -16364,     166,  -16344,    4332,
     130,  -16360,  -16361,     126,     217,  -32701,     216,  -16364,
   16450,  -32700,   16404,  -32701,  -32706,     216,   16405,   16407,
  -16222,    8414,     130,     217,  -32697,   16450,    1250,    4307,
    4318,     192,      93,     170,      90,     207,  -16365,   16404,
      90,  -16360,  -16365,   16404,     241,  -16365,   16404,     132,
     132,  -16360,    4329,  -16365,   16404,     133,     175,      90,
  -16365,   16404,     209,  -16365,   16404,    4313,     217,   16451,
    4263,   16384,   16384,     120,     216,  -32700,   16404,  -32706,
   16404,     243,   16409,     454,  -32685,   16404,     454,     248,
  -16365,   16404,    4263,     194,  -16360,    4329,  -32717,   16404,
    4263,   16407,     454,     237,     127,     215,     454,    4263,
   16384,  -16364,    1502,  -32629,  -16361,     153,  -32606,     222,
     143,  -32629,     153,     454,     126,   16409,     454,   16384,
     234,  -16365,  -32595,     147,  -32678,     234,     193,  -32677,
  -32676,  -32661,     109,  -32717,      53,      52,      52,      52,
     194,     194,     194,  -28581,    4188,     194,  -28566,    4203,
     194,  -28564,    4205,    4580,   16429,     183,     183,     186,
     186,  -28583,       0,    9437,      90,  -16365,       0,     134,
  -16365,       0,     210,    4329,     199,  -32677,  -32672,  -32676,
  -32688,  -32690,  -32705,  -32661,  -32659,  -32689,  -32686,  -32687,
  -16330,      65,  -32716,     186,  -28583,  -32717,  -32715,  -32713,
      52,  -32664,    4201,     186,  -32717,  -32715,      55,  -16328,
       0,     197,     197,      52,      52,     197,  -28581,  -28580,
     186,  -28581,    4188,    4318,     194,  -28581,    4188,    9437,
     194,     194,     454,   16407,     216,     194,  -28566,  -28565,
     186,  -28566,    4203,     194,  -28564,  -28563,     186,  -28564,
    4205,     183,     183,     186,     183,  -16365,       0,     183,
    4580,   16429,    5095,    9444,    5348,     186,  -28583,  -16328,
       0,   16409,  -16365,       0,    9437,    5348,     217,  -32701,
   16450,  -32701,     216,  -32700,       0,  -32701,  -32706,     216,
     243,     217,  -16318,       0,  -32552,       0,  -32700,       0,
  -32706,       0,     215,  -32550,     228,  -28616,  -28615,       0,
    4096,     218,     218,  -28616,       0,  -32677,  -32676,  -16361,
  -32710,  -32669,  -32662,  -32661,  -32660,  -32659,     740,  -32039,
     740,  -32719,    4096,     194,  -32719,  -32718,  -32604,  -32726,
  -32725,  -32724,  -32720,    4096,     710,    6116,  -32719,       0,
     710,    6116,  -28581,    4188,     218,     122,      50,   16409,
  -32726,  -32725,  -32724,  -32719,    4096,     710,     454,     195,
     195,     195,     454,  -28581,    4188,     194,  -28566,  -28565,
  -28564,    4205,     195,     195,     195,     710,    4836,    5095,
    4829,  -32726,  -32725,  -32724,  -32719,    4096,    4827,    4828,
     454,  -32720,  -32719,    4096,    4829,    4827,    4828,     194,
  -32719,       0,     710,    4836,  -16291,  -32677,      92,     184,
     121,  -28581,  -28580,  -32722,  -32723,    4317,  -32726,  -32725,
  -32724,       0,     183,  -32726,  -32725,  -32724,  -32720,       0,
    4316,     195,     195,     195,     454,  -28581,    4188,    4315,
     183,    4317,  -32726,  -32725,       0,     195,     195,    4315,
    4317,  -32726,       0,     195,  -32677,  -32676,  -16361,   16431,
     228,     228,      47,  -32610,  -32611,    5345,  -32609,  -32608,
  -32607,       0,    4320,    4319,    5345,  -32609,  -32608,       0,
    4319,    5345,  -32609,       0,  -32613,  -16361,   16431,     222,
     222,     156,  -32677,      92,     183,     186,    1222,   16435,
     228,   16403,    4324,     138,    8420,  -32723,    4189,      93,
     454,     148,  -32674,   16546,   16409,  -32597,     182,  -16383,
   16388,     234,  -16365,  -32595,     172,  -32678,     234,      90,
     244,     246,  -16365,       0,     235,  -32678,     234,  -16365,
     246,  -16365,       0,  -32678,     234,      90,   16407,     222,
   16405,     222,     145,   16407,     222,   16405,     222,     146,
   16407,    1252,     154,    5348,  -16365,     142,     126,     182,
  -16383,   16391,      90,  -16365,     127,  -32678,     238,      90,
     125,     239,  -16365,    8319,    8430,     128,     126,  -16361,
     127,     190,     240,     189,   16409,     182,  -16383,   16391,
      90,  -16365,       0,  -32678,     240,      90,   16623,  -16365,
       0,     244,     232,    1252,    1252,     137,    1252,     137,
    1252,     137,    1252,     137,    1252,     137,     222,  -16365,
       0,     131,     194,  -16360,  -16333,  -16332,     124,     181,
  -16292,  -16277,   16493,  -31802,    5342,  -28581,    4188,    4263,
     181,     186,     454,   16475,     183,  -28583,     199,    5598,
    9438,     222,  -32677,  -32676,   16407,     186,     228,     135,
   16409,  -32632,       0,  -32677,      92,  -32677,  -32676,  -32662,
  -32661,  -32660,  -32659,     165,  -32677,      92,     188,  -32662,
     107,     188,  -32660,     109,  -32732,      37,  -16344,    4318,
     148,  -32674,   16424,     222,   16405,     222,     174,  -28644,
  -32734,  -32680,  -28641,  -32733,  -32730,  -32735,  -32727,  -32738,
    4326,  -32738,  -32739,  -32741,  -32736,     199,  -28644,  -32680,
  -28641,    4326,  -32739,  -32741,     199,  -32738,  -32739,  -32741,
  -32736,  -32729,     199,  -32616,     199,  -32739,  -32741,  -32729,
     199,  -32616,  -32729,     199,  -28644,  -32680,    4326,  -32738,
  -32739,  -32741,     199,     245,    4318,     245,   16409,     152,
    4318,   16409,     152,     245,  -32672,  -32671,  -32670,      99,
   16407,     200,     144,     185,  -32677,      92,   16407,  -32582,
     200,     200,     187,     141,  -32677,      92,   16410,     191,
  -32677,  -32676,  -32662,  -32661,  -32660,     109,     198,
0(max grammar-718)

%ownshortintegerarray glink(0:max grammar) = %c
      -1,      70,      71,      37,      45,      46,      66,      66,
      74,      66,       0,      66,      50,      75,      78,      52,
      54,      79,      66,      80,      81,      82,      83,      25,
      40,      84,      85,      56,      56,      88,      92,      95,
      96,     101,     102,     103,     106,      45,      66,      66,
       0,     109,     109,     110,      51,      48,       0,      60,
      66,      61,       0,      66,       0,     110,     111,     111,
      57,     112,     113,     114,      63,      66,      65,     115,
     116,      67,       0,      66,     121,      66,       0,      72,
     122,     122,      66,      76,      66,      39,      76,      66,
      66,       0,     123,     126,     127,      86,      85,       0,
      89,     130,      88,       0,      93,      92,       0,     131,
      97,     136,      99,      96,       0,     137,      66,     104,
     103,       0,     107,     106,       0,      66,      66,      66,
     138,     139,     140,       0,     117,     119,     115,     141,
     115,      66,      70,     124,      66,       0,      66,     128,
      84,       0,     142,     132,     143,     134,     144,       0,
     155,     156,      58,     157,      66,     118,      90,     158,
     145,     144,     147,     145,     150,       0,     152,     152,
     153,     145,       0,      98,     159,      66,     133,     160,
     161,     164,     160,     140,     161,     161,     167,     171,
     173,     174,     175,     176,     177,     178,     181,     184,
     187,     188,     179,     189,     189,     182,     190,     190,
     185,     190,     190,       0,     187,     191,     192,     193,
       0,     195,       0,       0,     197,     196,       0,     200,
     199,       0,     203,     204,       0,     227,     231,     218,
     233,     234,       0,     235,     236,     237,       0,     231,
     225,     243,     244,     220,     247,     248,     249,     250,
     244,       0,     251,     228,     248,     249,     250,     252,
       0,       0,     187,     253,     259,     238,     268,     268,
     241,     190,     190,     269,     245,     271,     271,     228,
     272,     273,     274,     275,       0,     254,     265,     265,
     257,     266,     266,     260,     265,     265,     263,     266,
     266,     231,     267,     231,       0,     276,       0,     277,
     231,     272,     231,     281,     282,     278,     284,     252,
       0,       0,     285,       0,     231,       0,     287,       0,
     289,       0,     291,     293,       0,       0,     296,       0,
       0,     298,     300,       0,     302,       0,     304,       0,
     306,       0,       0,     309,     312,     313,     314,       0,
       0,     315,     310,     313,       0,     331,     331,     327,
     348,     349,     350,     350,     350,     350,     329,     281,
     351,     357,       0,     332,     340,     346,     358,     359,
     360,     361,     362,       0,     341,     342,     344,       0,
     345,       0,     268,     268,       0,       0,     365,     352,
     370,     371,     372,     373,       0,     374,     375,     376,
     382,     383,     363,     384,     384,     366,     268,     268,
     268,     268,     388,     389,     390,     391,     392,       0,
     377,     359,     360,     361,     340,       0,     378,     379,
     385,     362,     340,       0,     352,     353,     354,     374,
     394,       0,     395,       0,     399,     268,     268,     400,
       0,     410,     410,     405,     416,     406,     417,     418,
     419,       0,     411,     417,     418,     419,     420,       0,
     408,     405,     423,     416,     421,     424,     424,     407,
     414,     426,     429,     430,       0,     425,     431,     427,
     433,     435,       0,     432,     268,     268,     440,     441,
     281,     442,       0,     445,     450,     446,     445,     451,
     450,       0,     448,     447,     453,     452,     456,       0,
     454,     458,     457,       0,     268,     463,     464,     281,
     465,       0,     468,     468,     469,     470,     471,     472,
     473,     474,     475,     476,       0,     478,     268,     480,
       0,     482,     484,     484,     204,     489,     487,     495,
     496,     490,     493,     489,       0,     490,     490,       0,
     497,     498,     500,       0,       0,     503,     505,     509,
     498,     507,       0,     505,     505,     503,     511,     512,
     513,     514,       0,     516,     517,     518,     519,       0,
     521,     522,     523,     524,     521,       0,     527,     528,
     530,     535,     531,     533,       0,     531,       0,     536,
     537,     538,     540,     541,     541,       0,     543,     545,
       0,     546,     547,     548,     532,     550,     552,     557,
     553,     555,       0,     553,       0,     558,     559,     556,
       0,     562,     204,       0,     565,     563,     567,     564,
     569,     566,     571,     568,     573,     570,     575,     574,
       0,     578,     579,     591,     592,     583,     204,     584,
     587,     587,     587,     589,     204,     593,     593,     594,
     595,     596,     580,     599,     597,     600,       0,     204,
     204,     204,     605,     605,     606,     607,     608,     604,
     609,     611,       0,     192,     192,     192,     192,     192,
     192,     192,     192,       0,     622,     622,     191,     625,
     625,       0,     625,     625,     630,     632,     281,     281,
     633,     281,     281,     636,     637,     638,       0,     649,
     676,     683,     665,     654,     204,     204,     204,     204,
     649,     658,     667,     684,     665,       0,     661,     685,
     665,     661,     667,     684,       0,     669,     673,     688,
     665,     204,       0,     204,       0,     673,     688,     204,
       0,     665,     204,       0,     679,     691,     679,     658,
     667,     684,       0,     649,     686,     661,     687,     204,
     689,     690,     665,     679,     696,     696,     696,     696,
     697,     698,     699,       0,     702,     702,     703,     705,
     706,     707,     707,     699,     710,     710,     711,     712,
     718,     718,     718,     718,     718,     718,       0,
0(max grammar-718)

%constshortintegerarray kdict(32:596) = %c
       0,     511,     131,     531,     131,     551,     559,     131,
     567,     575,     583,     603,     623,     631,     663,     671,
     129,     129,     129,     129,     129,     129,     129,     129,
     129,     129,     691,     698,     707,     751,     795,     131,
     131,     824,     900,     960,    1076,    1120,    1280,     128,
     128,    1392,     128,     128,    1460,    1556,    1592,    1660,
    1748,     128,    1828,    2000,    2196,    2228,     128,    2268,
     128,     128,     128,    2287,    2295,    2327,    2335,    2355,
     131,     131,     131,     131,     131,     131,     131,     131,
     131,     131,     131,     131,     131,     131,     131,     131,
     131,     131,     131,     131,     131,     131,     131,     131,
     131,     131,     131,     131,    2363,     131,    2335,  -32351,
   16428,      25,   16428,      29,  -32349,   16433,       1,   16434,
       1,  -16127,       0,   16427,      21,   16407,       0,   16409,
       0,  -32323,  -10840,      40,   16471,       0,  -32341,  -10580,
      32,   16473,     117,   16384,      19,  -31955,  -32322,  -10580,
      36,   -9290,       0,   16473,     113,   16432,      13,  -32337,
   16427,      46,   16427,      17,   16405,       0,   16404,       0,
  -31556,  -31939,  -32322,   -9551,       2,   16433,       1,   16433,
       5,   16426,       5,  -31606,  -32323,   -9807,       0,  -32374,
   -9678,       0,   16436,       0,   16435,       0,  -31939,  -32322,
   16433,       4,   16426,       9,   16433,       3,  -30772,  -31666,
   10578,   11457,  -32344,   16413,       2,   16411,       2,      68,
  -32374,   16440,       0,   16440,       0,    8393,      83,   16408,
       0,  -31291,   10841,      69,  -32311,   16412,      18,   10830,
    9157,   10565,   16412,      18,    9415,      78,   16458,       0,
  -32049,    8665,    8908,   16455,       0,  -30131,      78,  -31277,
      84,  -32055,   10194,      76,   16469,       0,   10958,      69,
   16447,      32,      84,  -32319,   16418,       2,   10830,   16418,
       2,    8909,   10830,   16406,       0,  -31927,   10073,    9921,
    8649,   16419,       5,    9153,   10190,    8915,   16469,       1,
  -27956,  -31282,      88,  -31927,    8916,   10066,    9793,   16419,
       3,      84,   16447,       4,      68,  -32305,   16459,       2,
      70,  -30650,  -31284,      80,  -31931,   10194,   10567,    9921,
   16460,       1,    9938,   16461,       0,   10697,      84,   16467,
       3,    9801,      69,   16460,       0,    8915,   16452,       0,
  -29631,  -30903,  -31282,  -31793,   10069,   10819,   10185,      78,
   16416,       9,      82,   16445,       0,   16416,       9,    9422,
    9299,  -32315,   16453,       0,   10700,      69,   16454,       0,
   10700,      69,   16464,    1210,  -30778,      78,  -31549,    8916,
    8903,      82,  -32344,   16412,      17,   16472,      17,   10956,
    8900,   16470,       0,   16446,      44,  -30143,  -30647,   10063,
      71,  -31671,  -32302,   16412,      20,    8389,      76,   16412,
      36,   10830,    9157,   10565,   16412,      20,   10835,   16467,
       1,    8898,      76,   16425,       6,  -31935,   10063,   10825,
   10575,   16465,     109,      80,   16416,      10,  -32191,   10831,
   16442,       0,    8909,  -32314,   16414,       1,  -31794,   10069,
   10819,   10185,      78,   16416,      10,   16416,      10,  -30770,
  -31408,  -32174,   10071,   16418,       1,  -32374,   16441,       2,
   16441,       2,    9428,   10063,   16402,       0,  -32315,   16448,
       0,    8918,   10830,   16448,       0,  -30523,      82,  -31419,
  -31927,    9167,    8402,      77,   16457,       0,      77,   16419,
       6,    9412,    8387,    8916,   16415,     123,    9938,   16419,
       7,  -31931,   10959,    9428,    8910,   16415,     104,  -28351,
  -30397,  -31024,  -32045,   10964,   10066,   16464,    1319,    9813,
    7892,  -32323,   16462,    1384,   16463,    1241,    8389,      84,
   16456,       0,   10575,      68,  -32314,   16421,      64,   10575,
    8397,      84,  -32301,   16422,       9,    8912,      67,   16422,
      12,      76,   16412,      33,  -27704,  -28983,  -29488,  -31276,
  -31913,   10713,    8916,      77,   16419,       4,   10825,    9283,
   16417,      12,  -31423,  -31921,    9426,    9166,      40,   16420,
      48,      80,   16466,     115,   10834,   16451,       0,    8645,
   16423,       0,   10055,    9793,  -32315,   16449,       0,    8918,
   10830,   16449,       0,   10575,      84,  -32311,   16412,      19,
   10830,    9157,   10565,   16412,      19,  -32056,   10962,      69,
   16464,    1354,   10053,   16450,       0,      78,  -32052,    9428,
      76,   16444,     182,   10693,      83,   16446,      46,    9416,
    8908,   16443,     180,   16407,       0,  -31939,  -32292,  -10454,
      51,   16426,      13,   16433,       1,   16409,       0,  -32290,
  -10454,      51,   16426,      13,   16410,       0,   16431,      14,
  -32323,   16430,      51,   16433,       1
!!   %list
!!%endoffile
!***  end  of generated tables ***

%routine print ident(%integer p, mode)
   %INTEGER j, ad
   p = tag(p)_text
   %IF p = 0 %START
      %IF mode = 0 %THEN printsymbol('?') %C
                   %ELSE put('?')
      %RETURN
   %FINISH
   ad = addr(dict(p+1))
   %IF mode = 0 %THEN printstring(string(ad)) %ELSE %START
      putblock(byteinteger(ad),byteinteger(ad+1))
   %finish
%END
%ROUTINE abandon(%INTEGER n)
   %SWITCH reason(0:9)
   %INTEGER stream
   stream = listing
   %CYCLE
      newline %IF sym # nl
      printsymbol('*'); write(lines,4);  space
printsymbol('[')
write(n,0)
printsymbol(']')
      ->reason(n)
reason(*):debug("* Switch label not set: reason(".itos(n,0).")"); %stop
reason(0):printstring("compiler error!");          ->more
reason(1):printstring("switch vector too large");  ->more
reason(2):printstring("too many names");           ->more
reason(3):printstring("program too complex");      ->more
reason(4):printstring("feature not implemented");  ->more
{GT: reason(5):printstring(error message.sysmess(event_extra)) %and -> more %if event_sub # 1

reason(5):
          %if event_sub # 1 %start
            printstring("error message=""".error message.""" event_event=".itos(event_event,0)."  event_sub=".itos(event_sub, 0))
            {printstring("sysmess(event_extra)=""".sysmess(event_extra)."""")
            -> more 
          %finish

          %IF quote # 0 %START
            %IF quote < 0 %THEN printsymbol(cquote) %C
                          %ELSE printsymbol(squote)
          %ELSE
             printstring("%endof")
             %IF progmode >= 0 %THEN printstring("program") %C
                               %ELSE printstring("file")
          %FINISH
          printstring(" missing?");              ->more
reason(6):printstring("too many faults!");   ->more
reason(7):printstring("string constant too long"); ->more
reason(8):printstring("dictionary full"); -> more
reason(9): printstring("Included file ".include file." does not exist")
more: newline
      printstring("***  compilation abandoned ***");  newline
      %EXIT %IF stream = report
      close output
      stream = report
      select output(report)
   %REPEAT
   %monitor %IF diag&4096 # 0
   exit(16_1000002c)    {1000002c is SS$_ABORT with the inhibit message bit set - could just use EXIT_FAILURE}
%END

%routine op(%integer code, param)
   put(code);  putword(param)
%end
%routine set const(%integer m)
   %integer v
   v = m;  v = -m %if v < 0
   put('N');  putlong(v)
   put('U') %if m < 0
%end


%ROUTINE compile block(%INTEGER level, block tag, dmin, tmax, id)

   %INTEGERFNSPEC gapp
   %ROUTINESPEC delete names(%INTEGER quiet)
   %ROUTINESPEC analyse
   %ROUTINESPEC compile

   %INTEGER open; open       = closed;      !zero if can return from proc
   %INTEGER dbase; dbase      = dmax;        !dictionary base
   %INTEGER tbase; tbase      = tmax;        !tag base
   %INTEGER tstart; tstart    = tmax
   %INTEGER label; label      = 4;           !first internal label
   %INTEGER last array; last array = 0
   %INTEGER access; access     = 1;           !non-zero if accessible
   %INTEGER inhibit; inhibit    = 0;           !non-zero inhibits declaratons

   {GT:%SHORT}%INTEGERNAME bflags; bflags      == tag(block tag)_flags
   %INTEGER block type;          block type   = bflags>>4&7
   %INTEGER block form;          block form   = bflags&15
   %INTEGER block fm;          block fm     = tag(block tag)_format
   %INTEGER block otype;          block otype  = otype
   %INTEGERNAME block app;      block app   == tag(block tag)_app

   %INTEGER l, new app

%ROUTINE fault(%INTEGER n)

    ! -5 : -1  - warnings
    !  1 : 22  - errors

    %SWITCH fm(-5:22)
    %INTEGER st

    %ROUTINE print ss
       %INTEGER s, p
       %RETURN %IF pos = 0
       space
       p = 1
       %CYCLE
          printsymbol(marker) %IF p = pos1
          %EXIT %IF p = pos
          s = char(margin+p);  p = p+1
          %EXIT %IF s = nl %OR (s='%' %AND p = pos)
          %IF s < ' ' %START;         !beware of tabs
             %IF s = ff %THEN s = nl %ELSE s = ' '
          %FINISH
          printsymbol(s)
       %REPEAT
       pos = 0 %IF list <= 0
    %END

    pos1 = pos2 %IF pos2 > pos1
   %if n >=0 %or command&warnbit # 0 %start
    newline %IF sym # nl
    st = report
    st = listing %IF n = -3;              !don't report unused on the console
    %cycle
       SELECT OUTPUT(st)
       %if n < 0 %then printsymbol('?') %and pos1 = 0 %else printsymbol('*')
       %if st # report %start
          %if list <= 0 %and pos1 # 0 %start
             spaces(pos1+margin);  PRINTSTRING("      ! ")
          %finish
       %finish %else %start
          PRINTSTRING(include file) %if include # 0
          write(lines, 4);  printsymbol(csym);  space
       %finish
       ->fm(n) %if -5 <= n <= 22
       PRINTSTRING("fault");  write(n, 2);              ->ps
fm(*):debug("* Switch label not set: fm(".itos(n,0).")"); %stop
fm(-5):PRINTSTRING("Dubious statement");  dubious = 0;  ->psd
fm(-4):PRINTSTRING("Non-local")
       pos1 = for warn;  for warn = 0;      ->ps
fm(-3):print ident(x, 0);  PRINTSTRING(" unused");      ->nps
fm(-2):PRINTSTRING("""}""");                            ->miss
fm(-1):PRINTSTRING("access");                           ->psd

fm(0): PRINTSTRING("form");                             ->ps
fm(1): PRINTSTRING("atom");                             ->ps
fm(2): PRINTSTRING("not declared");                     ->ps
fm(3): PRINTSTRING("too complex");                      ->ps
fm(4): PRINTSTRING("duplicate");                        ->ps
fm(5): PRINTSTRING("type");                             ->ps
fm(6): PRINTSTRING("match");                            ->psd
fm(7): PRINTSTRING("context");                          ->psd
fm(21):PRINTSTRING("context ");  print ident(this, 0);  ->ps
fm(8): PRINTSTRING("%cycle");                           ->miss
fm(9): PRINTSTRING("%start");                           ->miss
fm(10):PRINTSTRING("size");  WRITE(lit, 1) %if pos1 = 0;->ps
fm(11):PRINTSTRING("bounds")
       WRITE(ocount, 1) %unless ocount < 0;             ->ps
fm(12):PRINTSTRING("index");                            ->ps
fm(13):PRINTSTRING("order");                            ->psd
fm(14):PRINTSTRING("not a location");                   ->ps
fm(15):PRINTSTRING("%begin");                           ->miss
fm(16):PRINTSTRING("%end");                             ->miss
fm(17):PRINTSTRING("%repeat");                          ->miss
fm(18):PRINTSTRING("%finish");                          ->miss
fm(19):PRINTSTRING("result");                           ->miss
fm(22):PRINTSTRING("format");                           ->ps
fm(20):printsymbol('"');  print ident(x, 0);  printsymbol('"')
miss:  PRINTSTRING(" missing");                         ->nps
psd:   pos1 = 0
ps:    print ss
nps:   NEWLINE
       %exit %if st = listing
       st = listing
    %repeat
   %finish
    %if n >= 0 %start
       %monitor %if diag&4096 # 0
       %if n # 13 %start;           !order is fairly safe
          ocount = -1
          gg = 0
          copy = 0;  quote = 0
          search base = 0;  escape class = 0
          gg = 0
       %finish
       faulty = faulty+1

       !check that there haven't been too many faults

       fault rate = fault rate+3;  abandon(6) %IF fault rate > 30
       fault rate = 3 %IF fault rate <= 0
    %FINISH
    tbase = tstart
    %IF list <= 0 %AND sym # nl %START
       error margin = column
       error sym = sym;  sym = nl
    %FINISH
%END

   dmin = dmin-1;  dict(dmin) = -1;            !end marker for starts & cycles
   abandon(2) %IF dmax = dmin

   %IF list > 0 %AND level > 0 %START
      write(lines, 5);  spaces(level*3-1)
      %IF block tag = 0 %START
         printstring("Begin")
      %FINISH %ELSE %START
         printstring("Procedure ");  print ident(block tag, 0)
      %FINISH
      newline
   %FINISH

   !deal with procedure definition (parameters)

   %IF block tag # 0 %START;                   !proc
      analyse;  compile %IF ss # 0

      %IF block otype # 0 %START;              !external-ish
         %IF bflags&spec = 0 %START;           !definition
            %IF progmode <= 0 %AND level = 1 %THEN progmode = -1 %C
                                             %ELSE fault(7)
!!!!!    %FINISH %ELSE %START;                                !external spec
!!!!!       bflags = bflags-spec;              !definition elsewhere
         %FINISH
      %FINISH

      new app = gapp;                          !generate app grammar
      %IF spec given # 0 %START;               !definition after spec
         fault(6) %IF new app # block app;     !different from spec
      %FINISH
      block app = new app;                     !use the latest

      %IF level < 0 %START;                    !not procedure definition
         delete names(0)
         %RETURN
      %FINISH
   %FINISH %ELSE %START
      open = 0;                                !can return from a block?
   %FINISH

   %CYCLE
      analyse
      %CONTINUE %IF ss = 0
      compile
      fault(-5) %IF dubious # 0
      %IF sstype > 0 %START;                   !block in or out
         %EXIT %IF sstype = 2;               !out
         compile block(spec mode, block x, dmin, tmax, id)
         %EXIT %IF ss < 0;                   !endofprogram
      %FINISH
   %REPEAT
   %IF list > 1 %AND level > 0 %START
      write(lines, 5);  spaces(level*3-1)
      printstring("End")
      newline
   %FINISH
   delete names(0)
   %RETURN

   %INTEGERFN gapp;                            !generate app grammar (backwards)
      %CONSTINTEGER comma = 140;               !psep
      %ROUTINESPEC set cell(%INTEGER g, tt)
      %ROUTINESPEC class(%RECORD(tagfm)%NAME v);   !imp77:
      %RECORD(tagfm)%NAME v;                       !imp77:
      %INTEGER p, link, tp, c, ap, t

      %RESULT = 0 %IF tmax = local;            !no app needed

      p = gmax1;  link = 0;  t = tmax

      %CYCLE
         v == tag(t);  t = t-1
         class(v);                             !deduce class from tag
         %IF c < 0 %START;                     !insert %PARAM
            c = -c
            set cell(196, tp)
            tp = -1
         %FINISH
         set cell(c, tp)
         %EXIT %IF t = local;                  !end of parameters
         set cell(comma, -1);                  !add the separating comma
      %REPEAT
      abandon(3) %IF gmax > gmin

      %RESULT = link

      %ROUTINE set cell(%INTEGER g, tt)

         !add the cell to the grammar, combining common tails

         %WHILE p # gmax %CYCLE
            p = p+1
            %IF glink(p) = link %AND gram(p) = g %START
               %IF tt < 0 %OR (gram(p+1) = tt %AND glink(p+1)=ap) %START
                  link = p;                    !already there
                  %RETURN
               %FINISH
            %FINISH
         %REPEAT

         !add a new cell

         gmax = gmax+1
         gram(gmax) = g
         glink(gmax) = link
         link = gmax

         %IF tt >= 0 %START;             ! set type cell
            gmax = gmax+1
            gram(gmax) = tt
            glink(gmax) = ap
         %FINISH

         p = gmax
      %END

      %ROUTINE class(%RECORD(tagfm)%NAME v);  !imp77:
         %CONSTINTEGER err    = 89
         %CONSTINTEGER rtp    = 100
         %CONSTINTEGER fnp    = 101
         %CONSTINTEGER mapp   = 102
         %CONSTINTEGER predp  = 103
         %CONSTINTEGERARRAY class map(0:15) = %C
         err,1764, 247, err(4), -rtp, -fnp, -mapp, -predp, err, 214,
         err, 229, err
         %INTEGER tags, type, form
         ap = 0
         tags = v_flags
         type = tags>>4&7;  form = tags&15
         tp = v_format<<3!type
         c = class map(form)
         c = 208 %AND tp = 0 %IF type = 0 %AND form = 2;  !%NAME
         ap = v_app %IF tags&parameters # 0
      %END
   %END

%ROUTINE delete names(%INTEGER quiet)
   %INTEGER flags
   %RECORD(tagfm)%NAME tx;      !imp77:
   %WHILE tmax > tbase %CYCLE
      x = tmax;  tmax = tmax-1
      tx == tag(x)
      flags = tx_flags
      fault(20) %IF flags&spec # 0 %and flags&own bit = 0
               {spec with no definition & not external}
      %IF flags&used bit = 0 %AND level > 0 %AND list <= 0 %START
         fault(-3) %IF quiet = 0;          !unused
      %FINISH
      dict(tx_text) = tx_link
   %REPEAT
%END

%ROUTINE analyse

   %CONSTINTEGER order bits = 16_3000, order bit = 16_1000
   %CONSTINTEGER escape     = 16_1000
   %INTEGER strp, mark, flags, prot err, k, s, c
   %OWNINTEGER key = 0
   {GT:%SHORT}%INTEGER node;      !imp77:
   {GT:%SHORT}%INTEGERNAME z;     !imp77:
   %RECORD(arfm)%NAME arp;  !imp77:
   %SWITCH act(actions:phrasal), paction(0:15)

   %ROUTINE trace analysis
      !diagnostic trace routine (diagnose&1 # 0)
      %INTEGER a
      %ROUTINE show(%INTEGER a)
         %IF 0 < a < 130 %START
            space
            printstring(text(a))
         %FINISH %ELSE write(a, 3)
      %END
      %OWNINTEGER la1=0, la2=0, lsa=0, lt=0
      newline %IF mon pos # pos %AND sym # nl
      mon pos = pos
      write(g, 3)
      space
      printstring(text(class))
      printsymbol('"') %IF gg&trans bit # 0
      a = gg>>8&15
      %IF a # 0 %START
         printsymbol('{')
         write(a, 0)
         printsymbol('}')
      %FINISH
      %IF atom1 # la1 %OR atom2 # la2 %OR lsa # subatom %C
                      %OR lt # type %START
         printstring(" [")
         la1 = atom1
         show(la1)
         la2 = atom2
         show(la2)
         lsa = subatom
         write(lsa, 3)
         lt = type
         write(lt, 5)
         printsymbol(']')
      %FINISH
      newline
   %END

%ROUTINE read sym

%routine get next source char
  %externalroutinespec readrecord(%integername len, %bytename b)
   %owninteger len=0
   %if sym = nl %start
      current char == char(1)
      readrecord (len, current char)                    ;! BUG??? readrecord reads from tanks but there are none to be read from in pass1.
      len = len + 1
      char(len) = nl
      pos = 0
      column = 0;           !???????????????????????????????????
   %finish
   pos = pos + 1
   sym = current char
!!   current char == BYTEINTEGER(ADDR(current char)+1) ; !! WAS  ++ 1
   current char == current char++1
   printsymbol(sym) %if list <= 0
   column = column + 1
%end

%CONSTBYTEINTEGERARRAY mapped(0:127) = %C
   0,  0,  0,  0,   0,  0,  0,  0,    0,  0, nl,  0,  3 ,  0,  0,  0,
   0,  0,  0,  0,   0,  0,  0,  0,    0,  0,  0,  0,   0,  0,  0,  0,
  0 ,'!','"','#', '$', 1 ,'&', 39,  '(',')','*','+', ',','-','.','/',
 '0','1','2','3', '4','5','6','7',  '8','9',':',';', '<','=','>','?',
 '@','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 , '|','}','~',  0

!!   0 = space
!!   1 = %
!!   2 = {
!!   3 = ff
!!   other values represent themselves

   %IF sym = nl %START
s1:   lines = lines+1
      printsymbol(end mark) %if end mark # 0
s11:  pos = 0;  pos1 = 0;  pos2 = 0;  margin = 0;  column = 0
      end mark = 0
      %IF list <= 0 %START
         %IF include # 0 %START
            printstring(" &");  write(lines, -4)
         %FINISH %ELSE  write(lines, 5)
         csym = cont;  printsymbol(csym)
         space
         %IF error margin # 0 %START
            lines = lines-1
            spaces(error margin)
            error margin = 0
            %IF error sym # 0 %START
               printsymbol(error sym)
               pos = 1;  char(1) = error sym
               sym = error sym;  error sym = 0
               ->s5
            %FINISH
         %FINISH
      %FINISH
s2:   symtype = 1
   %FINISH
s3:get next source char
s5:%IF sym # nl %START
      %RETURN %IF quote # 0;                     !dont alter strings
      sym = mapped(sym&127)
      %IF sym <= 3 %START;                       !special symbol
         ->s2 %IF sym = 0;                       !space (or dubious control)
         symtype = 2 %AND ->s3 %IF sym = 1;      !%
         cont = '+' %AND ->s11 %IF sym = 3;      !ff
         !must be {
         %CYCLE
            get next source char
            ->s3 %IF sym = '}'
            ->s4 %IF sym = nl
         %REPEAT
      %FINISH
      key = kdict(sym)
      %IF key&3 = 0 %AND symtype = 2 %START;            !keyword
         %IF sym = 'C' %AND current char = nl %START;     !%C...
            get next source char;  cont = '+';  ->s1
         %FINISH
      %ELSE
         symtype = key&3-2
      %FINISH
      %RETURN
   %FINISH
s4:cont = '+'
   symtype = quote
%END

%INTEGERFN format selected
   format list = tag(format)_app;          !number of names
   %IF format list < 0 %START;         !forward ref
      atom1 = error+22
      %RESULT = 0
   %FINISH
   %IF sym = '_' %START
      escape class = esc rec
      search base = tag(format)_format
   %FINISH
   %RESULT = 1
%END

%ROUTINE code atom(%INTEGER target)
   %INTEGER dbase, da
   %INTEGER base, n, mul, pend quote
   %INTEGER j,k,l, pt

   %ROUTINE lookup(%INTEGER d)
      %CONSTINTEGER magic = 6700421
      %INTEGER new name, vid, k1, k2, form
      %RECORD(tagfm)%NAME t;      !imp77:
      %INTEGER new

      !first locate the text of the name

      new = addr(dict(dmax+1))

            K2 = hash value*magic

            !*******************************************************

      k2 = k2>>(32-2*name bits)!1;         !IMP77:
      k1 = k2>>name bits;                       !giving name bits
      %CYCLE
         newname = hash(k1)
         %EXIT %IF newname = 0;                !not in
         ->in %IF string(addr(dict(newname+1))) = string(new)
         k1 = (k1+k2)&max names
      %REPEAT

      ! not found

      spare names = spare names-1
      abandon(2) %IF spare names <= 0
      hash(k1) = dmax;                !put it in
      dict(dmax) = -1
      newname = dmax;  dmax = dp;  ->not in

in:   search base = rbase %IF this >= 0 %AND d # 0;  !record elem defn
      %IF search base # 0 %START;               !record subname
         new = -1
         x = search base
         %CYCLE
            ->not in %IF x < format list
            %EXIT %IF tag(x)_text = new name
            x = x-1
         %REPEAT
      %FINISH %ELSE %START;                                  !hash in for normal names
         x = dict(newname)
         ->not in %IF x <= limit;         !wrong level
      %FINISH

      subatom = x;                            !name found, extract info
      t == tag(x)
      atom flags = t_flags
      format = t_format;  app = t_app
      protection = atom flags&prot
      type = atom flags>>4&7;  atom1 = amap(atom flags&15)

      %IF diag&8 # 0 %START
         printstring("lookup:")
         write(atom1, 3)
         write(type, 1)
         write(app, 3)
         write(format, 5)
         write(atom flags, 3)
         newline
      %FINISH

      %IF d = 0 %START;                                !old name wanted
         t_flags <- t_flags!used bit
         search base = 0

         %IF atom flags&subname # 0 %AND format # 0 %START; !a record
            %RETURN %IF format selected = 0
         %FINISH

         %IF atom flags&parameters # 0 %START;        !proc or array

            %IF app = 0 %START;                  !no parameters needed
               atom2 = atom1
               atom1 = atom1-4
               %IF 97 <= atom1 <= 98 %START
                  map gg = atom1;  atom1 = var
               %FINISH
            %FINISH %ELSE %START
               %IF sym = '(' %START
                  search base = 0;                  !ignore format for now
                  %IF atom1 >= 106 %START;             !arrays
                     app = phrase(app+200)
                     escape class = esc array
                     atom1 = (atom1-106)>>1+91;     !a,an->v  na,nan->n
                  %FINISH %ELSE %START;                            !procedures
                     escape class = esc proc
                     atom1 = atom1-4
                  %FINISH
                  phrase(200) = app
               %FINISH
            %FINISH
            pos2 = pos;  %return
         %FINISH

         !deal with constintegers etc

         %IF atom flags&const bit # 0 %AND atom1 = var %START
               map gg = const;  atom2 = const
               subatom = -subatom %IF type = integer
         %FINISH
         %RETURN

      %FINISH
                                                 !new name wanted
      ->not in %IF tbase # tstart;               !dont fault proc parm-parm
      %IF d = lab+spec+used bit %START
         t_flags = t_flags!used bit
         %RETURN
      %FINISH
      %IF atom flags&spec # 0 %START;                 !a spec has been given
         %IF d = lab %START;                     !define label
            t_flags <- lab!used bit
            %RETURN
         %FINISH
         %IF 7 <= decl&15 <= 10 %AND decl&spec = 0 %START

            !procedure definition after spec

            %IF (decl!!atom flags)&2_1111111 = 0 %START;  !correct type?
               t_flags = t_flags-spec
               spec given = 1
               %RETURN
            %FINISH

            !note that an external procedure must be speced as a
            !non-external procedure.

         %FINISH
         %IF decl&15 = recfm %START;                   !recordformat
            t_flags = record<<4+recfm
            t_format = fdef
            %RETURN
         %FINISH
      %FINISH
      %RETURN %IF last1 = jump %AND atom1 = swit
      copy = pos1 %IF copy = 0

notin:app = 0;  vid = 0
      atom1 = error+2

      %return %if d = 0;                               !old name wanted
      type = d>>4&7;  form = d&15;  atom1 = amap(form)

      %IF this < 0 %START;                       !normal scope
         new = newname
         tmax = tmax+1;  x = tmax
      %FINISH %ELSE %START;                      !recordformat scope
         new = -1
         recid = recid-1;  vid = recid
         tmin = tmin-1;  x = tmin
         format list = tmin
      %FINISH

      %IF 11 <= form <= 14 %START;                     !arrays
         dim = 1 %IF dim = 0;           !set dim for owns
         app = dim
      %FINISH

      d = d!used bit %IF (otype > 2 %AND d&spec = 0) %OR perm # 0

      !external definitions need not be used in the file in which
      !they are defined, so inhibit a useless unused warning.

      t == tag(x)
      %IF form = lab %START
         id = id+1;  vid = id
      %FINISH
      t_index = vid
      t_text   = new name
      t_flags <- d
      t_app    = app
      t_format = fdef;  format = fdef
      subatom = x

      %IF new >= 0 %START;                             !insert into hash table
         t_link = dict(new);  dict(new) = x
         %IF gmin = max grammar %START;                !proc param params
            tmin = tmin-1;  subatom = tmin
            tag(tmin) = t
         %FINISH
      %FINISH
      abandon(3) %IF tmax >= tmin
   %END



top:  pos1 = pos
      subatom = 0;  pend quote = 0

      !app and format must be left for assigning to papp & pformat

      ->name %IF symtype = -2;                   !letter
      ->number %IF symtype < 0;                  !digit
      %IF symtype = 0 %START
         atom1 = termin;  atom2 = 0
         %RETURN
      %FINISH
      %IF symtype # 2 %START;                    !catch keywords here
         ->text %IF quote # 0;                   !completion of text
         ->strings %IF sym = squote;             !start of string
         ->symbols %IF sym = cquote;             !start of symbol
         ->number %IF sym = '.' %AND '0' <= current char <= '9'
      %FINISH

                                                 !locate atom in fixed dict
      k = key>>2;  read sym
      %CYCLE
         j = kdict(k)
         %EXIT %IF j&16_4000 # 0
         %IF j&127 # sym %OR symtype < 0 %START
            ->err %UNLESS j < 0
            k = k+1
         %FINISH %ELSE %START
            l = j>>7&127;  read sym
            %IF j > 0 %START
               %IF l # 0 %START
                  ->err %IF l # sym %OR symtype < 0
                  read sym
               %FINISH
               l = 1
            %FINISH
            k = k+l
         %FINISH
      %REPEAT
      atom1 = j&127
      %IF atom1 = 0 %START;                      !comma
         atom1 = 19;  subatom = 19;  atom2 = 0
         %IF sym = nl %START
            %RETURN %IF ocount >= 0

            !special action needs to be taken with <comma nl> as
            !const array lists can be enormous

            read sym
         %FINISH
         %RETURN
      %FINISH
      atom2 = j>>7&127
      subatom = kdict(k+1)&16_3fff
      !!!!!cont = ' '
      %RETURN

      !report an error. adjust the error marker (pos1) to point
      !to the faulty character in an atom, but care needs to be taken
      !to prevent misleading reports in cases like ...?????

err:  atom1 = error+1;  atom2 = 0
      pos1 = pos %IF pos-pos1 > 2
      %RETURN

        !take care with strings and symbol constants.
        !make sure the constant is valid here before sucking it in
        !(and potentially loosing many lines)

symbols:atom1 = var;  atom2 = const;  type = integer
        map gg = const;  protection = prot
        subatom = lp;  abandon(3) %IF lp >= lit max
        quote = \pend quote
        %RETURN

      !an integer constant is acceptable so get it in and
      !get the next atom

chars:n = 0;  cont = cquote
      %CYCLE
         read sym
         %IF sym = cquote %START
            %EXIT %IF current char # cquote
            read sym
         %FINISH
         %IF n&(\((-1)>>byte size)) # 0 %START; ! overflow
            pos1 = pos;  atom1 = error+10;  %RETURN
         %FINISH
         ->err %IF quote = 0
         n = n<<byte size+sym
         quote = quote+1
      %REPEAT
      quote = 0;  cont = ' '
      readsym %IF sym # nl
      lit pool(lp) = n;  lp = lp+1
      ->top

        !sniff the grammar before getting the string

strings:atom1 = var;  atom2 = const;  type = stringv
        subatom = (strp-stbase)!16_4000
        map gg = const;  protection = prot
        quote = subatom
        text line = lines;                  !in case of errors
        %RETURN

      !a string constant is ok here, so pull it in and get
      !the next atom

text: ->chars %IF quote < 0;                    !character consts
      l = strp; n = strp
      j = addr(glink(gmin-1));                  !absolute limit
      k = l+256;                                !string length limit
      k = j %IF j < k;                          !choose lower

      %CYCLE
         cont = squote;  quote = 1
         %CYCLE
            read sym
            %IF sym = squote %START;               !terminator?
               %EXIT %IF current char # squote;      !yes ->
               read sym;                           ! skip quote
            %FINISH
            l = l+1;  byteinteger(l) = sym
            lines = text line %AND abandon(7) %IF l >= k;    !too many chars
         %REPEAT
         byteinteger(n) = l-n;               !plug in length

         strp = l+1;                               !ready for next string
         quote = 0;  cont = ' ';  read sym
         code atom(target)
         %RETURN %UNLESS atom1 = 48 %AND sym = squote;    !fold "???"."+++"
      %REPEAT

      %ROUTINE get(%INTEGER limit)
         %INTEGER s, shift
         shift = 0
         %IF base # 10 %START
            %IF base = 16 %START
               shift = 4
            %FINISH %ELSE %START
               %IF base = 8 %START
                  shift = 3
               %FINISH %ELSE %START
                  %IF base = 2 %START
                     shift = 1
                  %FINISH
               %FINISH
            %FINISH
         %FINISH
         n = 0
         %CYCLE
            %IF symtype = -1 %START;            !digit
               s = sym-'0'
            %FINISH %ELSE %START
               %IF symtype < 0 %START;                  !letter
                  s = sym-'A'+10
               %FINISH %ELSE %START
                  %RETURN
               %FINISH
            %FINISH
            %RETURN %IF s >= limit
            pt = pt+1;  byteinteger(pt) = sym
            %IF base = 10 %START;            !check overflow
               %IF n >= max int %AND (s > max dig %OR n > max int) %START

                  !too big for an integer,
                  !so call it a real

                  base = 0;  type = real;  n = 0
               %FINISH
            %FINISH
            %IF shift = 0 %START
               n = n*base+s
            %FINISH %ELSE %START
               n = n<<shift+s
            %FINISH
            read sym
         %REPEAT
      %END

number:base = 10
bxk:   atom1 = var;  atom2 = const;  type = integer;  subatom = lp
       map gg = const;  protection = prot
       abandon(3) %IF lp >= lit max
       pt = strp;  mul = 0
       %CYCLE
          get(base)
          %EXIT %UNLESS sym = '_' %AND base # 0 %AND pend quote = 0;    !change of base
          read sym
          base = n
       %REPEAT

       %IF pend quote # 0 %START
          ->err %IF sym # cquote
          readsym
       %FINISH
       %IF sym = '.' %START;                        !a real constant
          pt = pt+1;  byteinteger(pt) = '.'
          read sym
          type = real;  base = 0;  get(10)
       %FINISH
       %IF sym = '@' %START;                        !an exponent
          pt = pt+1;  byteinteger(pt) = '@';  k = pt
          readsym
          type = integer;  base = 10
          %IF sym = '-' %START
             read sym;  get(10);  n = -n
          %FINISH %ELSE %START
             get(10)
          %FINISH
          pt = k+1;  byteinteger(pt) = lp;  litpool(lp) = n;  lp = lp+1
          atom1 = error+10 %IF base = 0
          type = real;                              !exponents force the type
       %FINISH

       %IF type = real %START
          byteinteger(strp) = pt-strp
          subatom = (strp-stbase)!16_2000;  strp = pt+1
       %FINISH %ELSE %START
          litpool(lp) = n
          lp = lp+1
       %FINISH
       %RETURN

name: atom1 = 0 %AND %RETURN %IF 27 <= target <= 41
      hash value = 0

      !*****************************
      !*machine dependent for speed*
      !*****************************

      dp = dmax+1
      da = addr(dict(dp));  dbase = da
      %CYCLE
         hash value = hash value+(hash value+sym);        !is this good enough?
         da = da+1;  byteinteger(da) = sym
         read sym
         %EXIT %IF symtype >= 0
      %REPEAT
      %IF sym = cquote %START
         pend quote = 100
         ->symbols %IF hash value = 'M'
         read sym
         %IF hash value = 'X' %THEN base = 16 %AND ->bxk
         %IF hash value = 'K' %C
         %OR hash value = 'O' %THEN base = 8 %AND ->bxk
         %IF hash value = 'B' %THEN base = 2 %AND ->bxk
         ->err
      %FINISH
      n = da-dbase
      byteinteger(dbase) = n
      dp = dp+(n+2)>>1
      abandon(8) %IF dp >= dmin

      atom2 = 90;                  !ident
      %IF last1 = 0 %AND sym = ':' %START;           !label
         limit = local;  lookup(lab);  %RETURN
      %FINISH
      %IF last1 = jump %START;                 !->label
         limit = local;  lookup(lab+spec+used bit);  %RETURN
      %FINISH
      %IF decl # 0 %AND target = 90 %START;    !identifier
         search base = fm base
         limit = local;  lookup(decl)
         search base = 0
      %FINISH %ELSE %START
         limit = 0;  lookup(0)
      %FINISH
   %END

   %INTEGERFN parsed machine code
      !   *opcode_??????????
      %routine octal(%integer n)
         %integer m
         m = n>>3
         octal(m) %if m # 0
         put(n&7+'0')
      %end
      atom1 = error %AND %RESULT=0 %UNLESS symtype = -2;  !starts with letter
      put('w')
      %CYCLE
         put(sym)
         read sym
         %EXIT %IF symtype >= 0;           !pull in letters and digits
      %REPEAT
      put('_')
      %IF symtype # 0 %START;                !not terminator
         atom1 = error %AND %result=0 %UNLESS sym = '_'
         read sym
         %WHILE symtype # 0 %CYCLE
            %IF symtype < 0 %START;             !complex
               code atom(0);  %result=0 %IF atom1&error # 0
               %IF atom2 = const %AND type = integer %START
                  %IF subatom < 0 %THEN octal(tag(-subatom)_format) %C
                                  %ELSE octal(litpool(subatom))
               %FINISH %ELSE %START
                  %IF 91 <= atom1 <= 109 %START
                     put(' '); octal(tag(subatom)_index)
                  %FINISH %ELSE %START
                     atom1 = error;  %result=0
                  %FINISH
               %FINISH
            %FINISH %ELSE %START
               put(sym);  read sym
            %FINISH
         %REPEAT
      %FINISH
      put(';')
      %RESULT=1
   %END

   cont = ' ' %IF gg = 0
   last1 = 0;  mapgg = 0
   s = 0;  ss = 0;  sstype = -1; fdef = 0
   fm base = 0
   app = 0

   !deal with alignment following an error in one statement
   !of several on a line

   margin = column;                         !start of statement

   pos = 0
   stbase = addr(glink(gmax+1));  strp = stbase;  lp = 0
   tbase = tstart;               !??????????????
   local = tbase

   %IF gg = 0 %or ocount >= 0 %START;            !data or not continuation(z)
again:%WHILE sym type = 0 %CYCLE;                !skip redundant terminators
         c = cont
         cont = ' ';  cont = '+' %IF ocount >= 0
         read sym
         cont = c
      %REPEAT
      ->skip %IF sym = '!';                      !comment
      this = -1
      code atom(0)
      %IF atom1 = comment %START
skip:    quote = 1
         c = cont
         read sym %AND cont = c %WHILE sym # nl; !skip to end of line
         quote = 0;  symtype = 0
         ->again
      %FINISH
   %FINISH
   decl = 0;  mark = 0
   gentype = 0;  force = 0
   dim = 0;  prot err = 0
   node = 0;  nmax = 0;  nmin = rec size+1
   order = 1;  gmin = max grammar+1
   sstype = 0 %AND ->more %IF gg # 0;             !continuation
   ptype = 0;  spec given = 0

   stats = stats+1;  op('O', lines) %IF perm = 0

   ->fail1 %IF atom1&error # 0;                  !first atom faulty

   %IF escape class # 0 %START;                  !enter the hard way after
      g = imp phrase;  sstype = -1;  ->a3
   %FINISH

   g = initial(atom1);                           !pick up entry point
   %IF g = 0 %START;                             !invalid first atom
      g = initial(0);  sstype = 0;  ->a3;        !declarator?
   %FINISH
   %IF g < 0 %START;                             !phrase imp
      g = g&255
      nmax = 1
      ar(1)_class = 0;  ar(1)_link = 0;  ar(1)_sub = imp phrase
   %FINISH

   gg = gram(g);  class = gg&255;  sstype = gg>>12&3-1
   ->a1

act(194): ptype = type;  papp = app;  pformat = format;  ->more
act(196):k =g+1;  ->a610
act(188):k = ar(nmax)_sub+1
a610:     papp = glink(k)
          k = gram(k)
          ->more %IF k = 0;                        !%NAME
          ptype = k&7;  pformat = k>>3
act(183):k = type;  gentype = k %IF gentype = 0 %OR k = real
          %IF pformat < 0 %START;               !general type
             app = papp;  format = pformat
             k = real %IF ptype = real %AND type = integer
             k = force %AND force = 0 %IF force # 0
          %FINISH
          ->fail2 %UNLESS papp = app %AND (ptype = k %OR ptype = 0)
          ->more %IF pformat=format %OR pformat = 0 %OR format = 0
          ->fail2
act(197):arp == ar(nmin)
         k = arp_sub
         ->fail3 %UNLESS block form = k&15
         arp_sub = k>>4

         type = block type
         ptype = block type;  pformat = block fm;  papp = app
         pformat = -1 %IF ptype # record
         ->more
act(195):arp == ar(nmin)
         k = arp_sub
         arp_sub = k>>2
         k = k&3
                                                      !1 = check integer
                                                      !2 = check real
                                                      !3 = check real + int
          ->more %IF k = 0;                             !no action
          %IF k = 1 %START
             force = integer
             ->more %IF type = integer %OR type = 0
             ->fail2
          %FINISH
          ->fail2 %UNLESS ptype = real %or ptype = 0
          force = integer %IF k = 3
          ->more
act(198):!%OTHER
         k = gg>>8&15
         %IF k = 0 %START;      !restore atom
            atom1 = last1
            ->more
         %FINISH
         %IF k = 1 %START;      !test string
            ->fail2 %UNLESS type = stringv
            ->more
         %FINISH
         %if k = 2 %start
            ->fail2 %if type = record
            -> more
         %finish
         %if k = 3 %start;         !check OWN variable coming
            code atom(0)
            ->A7 %if atom flags&own bit = 0
            ->more
         %finish
         for warn = pos1 %IF x <= local;      !%FORTEST
         ->more
paction(1):%IF type = record %THEN g = phrase(242) %ELSE pformat = -1
                                               ->a3
paction(2):ptype = real;     pformat = -1;     ->a3
paction(3):ptype = stringv;  pformat = -1;     ->a3
paction(4):ptype = integer;  pformat = -1;     ->a3
paction(5):->a3 %if ptype = integer
           g = phrase(212) %AND pformat=-1 %IF ptype = real
           g = phrase(213) %IF ptype = stringv
           ->a3
paction(6):ptype = gram(ar(nmax)_sub+1)&7;  pformat = -1;  ->a3
paction(7):ptype=real %IF ptype = integer;  pformat=-1; ->a3

a1:   last1 = class;  atom1 = 0;  s = subatom

a2:   %IF gg&trans bit = 0 %START;                !insert into analysis record
         z == node
         %CYCLE;                                  !insert cell in order
            k = z
            %EXIT %IF gg&order bits = 0 %OR k = 0
            gg = gg-order bit;  z == ar(k)_link
         %REPEAT
         gg = map gg %IF map gg # 0 %AND gg&255 = var
         nmin = nmin-1;  ->fail0 %IF nmin = nmax
         z = nmin
         arp == ar(nmin)
         arp_sub = s;  arp_class = (gg&255)!mark
         arp_link = k
      %FINISH
      mark = 0;  map gg = 0

more: g = glink(g);                               !chain down the grammar

paction(0):
a3:   gg = gram(g);  class = gg&255            ;! <------------------------------ gg set to -1...  THIS CAUSES MISSING SWITCH LABEL paction(15) BELOW
debug("gg = gram(g) = -1 ... g=".itos(g,0)." gg=".itos(gg,0)) %if gg = -1
      trace analysis %IF diag&1 # 0
      ->a5 %IF class = 0;                         !end of phrase

      %IF class < actions %START;                 !not a phrase or an action
         class = atomic(class) %IF class >= figurative
         ->a2 %IF class >= manifest
         code atom(class) %IF atom1 = 0
         %IF escape class # 0 %START;             !escape to new grammar
            class = escape class;  escape class = 0
            g = g+escape

            !note that following an escape the next item is
            !forced to be transparent!

esc:        gg = 0
            arp == ar(nmax+1)
            arp_papp = papp;  arp_x = x;  ->a4
         %FINISH

         ->a1 %IF class = atom1 %OR class = atom2

a7:      ->fail1 %IF gg >= 0;                     !no alternative
         g = g+1
         ->a3
      %FINISH

      %IF class >= phrasal %START;                !a phrase
a4:      nmax = nmax+1;  ->fail0 %IF nmax = nmin
         arp == ar(nmax)
         arp_ptype = ptype
         arp_pos = pos1
         arp_pformat = pformat
         arp_link = gentype
         arp_class = node
         arp_sub = g
         node = 0
         g = phrase(class)
         ptype = force %AND force = 0 %IF force # 0
         gentype = 0
         ->paction(gg>>8&15)                                                       ;! <----------------- CAUSES CRASH
paction(*):debug("* Switch label not set: paction(".itos(gg>>8&15,0).") {gg=".itos(gg,0)."}"); %stop {avoid executing random code}
      %FINISH

      ->act(class);                               !only actions left
act(*):debug("* Switch label not set: act(".itos(class,0).")"); %stop
a5:   !reverse links

      s = 0
      %WHILE node # 0 %CYCLE
         z == ar(node)_link
         k = z;  z = s;  s = node;  node = k
      %REPEAT
      ss = s

a6:   %IF nmax # 0 %START
         k = gentype;                             !type of phrase
         arp == ar(nmax);  nmax = nmax-1
         node = arp_class
         gentype = arp_link
         ptype = arp_ptype
         pformat = arp_pformat
         g = arp_sub
         %IF g&escape # 0 %START
            g = g-escape
            papp = arp_papp
            mark = 255
            subatom = s
            ->a3
         %FINISH
         gentype = k %IF gentype = 0 %OR k = real
         type = gen type

         k = gg;                                  !exit-point code
         %CYCLE
            gg = gram(g)
            ->a2 %IF k = 0
            ->fail1 %IF gg >= 0;                  !no alternative phrase
            k = k-order bit
            g = g+1;                              !sideways step
         %REPEAT

      %FINISH

      pos1 = copy %AND fault(4) %IF copy # 0
      fault(13) %IF order = 0
      fault(-4) %IF for warn # 0
      pos1 = 0
      fault rate = fault rate-1
      %RETURN

act(193):gg = 0 %AND ->a5 %UNLESS sym = '=' %or sym = '<'; !cdummy
act(181):atom1 = amap(decl&15);                             !dummy
         ->more

act(182):class = escdec;  g = glink(g)!escape
         decl = 0;  otype = 0;  ->esc;                      !decl

act(199):
         !reverse links;                                     !compile

         s = 0
         %WHILE node # 0 %CYCLE
            z == ar(node)_link
            k = z;  z = s;  s = node;  node = k
         %repeat
         ss = s

         code atom(28) %IF quote # 0;                       !expend
         compile;  ->more %IF atom1&error = 0
         ->fail1

act(184):->fail4 %UNLESS type = integer
         %IF subatom < 0 %THEN lit = tag(-subatom)_format %C
                         %ELSE lit = lit pool(subatom)
         ->fail4 %IF lit # 0
         ->more
act(185):                                                   !apply parameters
         s = 0
         %WHILE node # 0 %CYCLE
            z == ar(node)_link
            k = z;  z = s;  s = node;  node = k
         %REPEAT
         ss = s

         atom1 = ar(s)_class;  atom2 = 0
         atom1 = var %IF atom1 = 97 %OR atom1 = 98
         arp == ar(nmax)
         x = arp_x
         pos1 = arp_pos
         pos2 = 0
         app = 0
         format = tag(x)_format
         flags = tag(x)_flags
         type = flags>>4&7
         protection = flags&prot
         protection = 0 %IF flags&aname # 0

         %IF flags&subname # 0 %AND format # 0 %START
            ->fail1 %if format selected = 0
         %FINISH

         ->a6

act(187):protection = prot;  ->more;                      !%SETPROT
act(186):->more %if protection&prot = 0
         prot err = nmin
         -> a7
act(191):k = protection;                           !%GUARD
         code atom(0)
         protection = k %IF atom flags&aname = 0
         ->more

act(192):->fail1 %IF parsed machine code=0
         ->more

act(189):k = gapp;                                     !%GAPP
         delete names(1)
         tmax = tbase;  tbase = gram (gmin);           !restore tmax
         local= tbase
         gmin = gmin+1

         x = ar(ar(nmax)_class)_sub
         tag(x)_app = k;                               !update app
         ->more

act(190):gmin = gmin-1;                                !%LOCAL
         abandon(2) %IF gmin <= gmax
         gram (gmin) = tbase;  tbase = tmax
         local = tbase
         ->more

! errors

fail4:k = error+10;            ->failed;        !*size
fail3:k = error+7;             ->failed;        !*context
fail2:k = error+5;  pos2 = 0;  ->failed;        !*type
fail0:k = error+3;             ->failed;        !*too complex
fail1:k = atom1;  pos2 = 0

failed:
      %IF diag&32 # 0 %START
         printstring("Atom1 =")
         write(atom1, 3)
         printstring("  Atom2 =")
         write(atom2, 3)
         printstring("  subatom =")
         write(subatom, 3)
         newline
         printstring("Type =")
         write(type, 1)
         printstring("   Ptype =")
         write(ptype, 1)
         newline
         printstring("App =")
         write(app, 1)
         printstring("   Papp =")
         write(papp, 1)
         newline
         printstring("Format =")
         write(format, 1)
         printstring("   Pformat =")
         write(pformat, 1)
         newline
         %monitor
       %FINISH

       quote = 0 %AND readsym %WHILE sym # nl %AND sym # ';'
       %IF k&error # 0 %START
          fault(k&255)
       %FINISH %ELSE %START
         %IF prot err = nmin %THEN fault(14) %ELSE fault(0)
       %FINISH
       gg = 0;  ss = 0;  symtype = 0
   %END;                                               !of analyse

   %ROUTINE compile

      %CONSTINTEGER then = 4, else = 8, loop = 16

      %SWITCH c(0:actions), litop(1:12)

      %CONSTBYTEINTEGERARRAY operator(1:14) = %C
                         '[',  ']',  'X',  '/', '&',  '!',  '%',  '+',
                         '-',  '*',  'Q',  'x', '.',  'v'

      %CONSTBYTEINTEGERARRAY cc(0 : 7) = '#','=',')','<','(','>', 'k','t'

      %CONSTBYTEINTEGERARRAY anyform(0:15) = 1,0,1,1(4),1,0,1,1,0,1,1,1,1

      %CONSTSHORTINTEGERARRAY decmap(0:15) = %C
         1,             2,
         16_100B,       16_100D,       16_140C,      16_140E,
         3,             4,
         16_1007,       16_1008,       16_1009,      16_100A,
         6,             0,             0,            0
      %OWNBYTEINTEGERARRAY cnest(0:15)
      %INTEGER lmode, clab, dupid
      %INTEGER resln
      %OWNINTEGER last def = 0
      %OWNINTEGER lb, ub
      %INTEGER cp, ord
      %INTEGER next, link, j, k, n, done
      %INTEGER class
      %INTEGER lit2, defs, decs, cident
      %INTEGER pending;  %OWNINTEGERARRAY pstack(1:40)
      %OWNSTRING(8) name = ""
      %OWNINTEGER count = 0

      %ROUTINE def lab(%INTEGER l)
         op(':', l)
         access = 1
      %END

      %ROUTINE get next
         %RECORD(arfm)%NAME p;      !imp77:
gn:      %IF next = 0 %START;                        !end of phrase
            class = 0 %AND %RETURN %IF link = 0;     !end of statement
            p == ar(link)
            next = p_link
            link = p_sub
         %FINISH
         %CYCLE
            p == ar(next)
            x = p_sub
            class = p_class
            %EXIT %IF class < actions;               !an atom
            %IF x = 0 %START;                        !null phrase
               next = p_link;  ->gn
            %FINISH
            %IF p_link # 0 %START;                   !follow a phrase
               p_sub = link;  link = next
            %FINISH
            next = x
         %REPEAT
         next = p_link
         %IF diag&2 # 0 %START
            spaces(8-length(name)) %UNLESS name = ""
            name = text(class)
            write(x, 2)
            space
            printstring(name)
            space
            count = count-1
            %IF count <= 0 %START
               count = 5
               name = ""
               newline
            %FINISH
         %FINISH
      %END

      %ROUTINE set subs(%INTEGER n)

         !update the app field in n array descriptors

         %INTEGER p
         p = tmax
         %WHILE n > 0 %CYCLE
            %SIGNAL 15,15 %IF p < tbase
            tag(p)_app = dimension
            p = p-1;  n = n-1
         %REPEAT
      %END

      %ROUTINE set bp

         !define a constant bound pair from the last stacked constants

         pending = pending-2
         lb = pstack(pending+1);  ub = pstack(pending+2)
         %IF ub < lb-1 %START
            pos1 = 0;  next = link;  fault(11)
            ub = lb
         %FINISH
         set const(lb);  set const(ub)
         put('b') %UNLESS class = 146
      %END

      %ROUTINE compile end(%INTEGER type)

         ! type = 0:eof, 1:eop, 2:end

         %IF access # 0 %START
            open = 0
            fault(19) %IF block form > proc;           !can reach end
         %FINISH

         %WHILE dict(dmin) >= 0 %CYCLE;                !finishes & repeats
            fault(17+dict(dmin)&1)
            dmin = dmin+1
         %REPEAT
         {delete names(0)}
         put(';')
         put(';') %IF type = 1;       !endofprogram

         bflags = bflags!open;                         !show if it returns

         def lab(0) %IF block tag # 0 %AND level # 1;  !for jump around
         %IF type # 2 %START;                          !eop, eof
            fault(16) %IF level # type;                !end missing
         %FINISH %ELSE %START
            %IF level = 0 %START
               fault(15);                                 !spurious end
            %FINISH
         %FINISH

         !end mark = 11;               !IMP77
      %END

      %ROUTINE def(%INTEGER p)

         !dump a descriptor

         %INTEGER t, f, type
         %RECORD(tagfm)%NAME v;      !imp77:
         defs = defs+1
         v == tag(p)
         t = 0
         put('$')
         %UNLESS v_index < 0 %START;                   !no index for subnames
            id = id+1 %AND v_index = id %IF v_index = 0
            last def = v_index
            putword(lastdef)
         %FINISH %else putword(0)
         print ident(p, 1);                            !output the name
         t = v_flags
         type = t
         type = type&(\(7<<4)) %IF type&(7<<4) >= 6<<4;!routine & pred
         put(','); put(type&2_1111111);            !type & form
         f = v_format
         f = tag(f)_index %IF t&16_70 = record<<4
         f = v_index %IF f < 0
         op(',', f);               !format
         f = otype+t>>4&2_1111000
         f = f!8 %IF class = 125;                      !add spec from %DUP
         dim = v_app;                  !dimension
         dim = 0 %unless 0 < dim <= dim limit
         put(','); putlong(f+dim<<8);                              !otype & spec & prot
         defs = 0 %IF t&parameters = 0
         f = t&15
         %IF v_flags&spec # 0 %START
            v_flags = v_flags&(\spec) %UNLESS 3 <= f <= 10
            ocount = -1;             ! external specs have no constants
         %FINISH
         dimension = 0
         %if otype = 2 %and (f=2 %or f=12 %or f=14) %start
            v_flags = v_flags-1;            !convert to simple
         %finish
      %END

      %ROUTINE def s lab(%INTEGER n)

         !define a switch label, x defines the switch tag

         %INTEGER p, l, b, w, bit
         p = tag(x)_format;                            !pointer to table
         l = dict(p);                                  !lower bound
         %IF l <= n <= dict(p+1) %START
            b = n-l
            w = b>>4+p
            bit = 1<<(b&15)
            %IF dict(w+2)&bit # 0 %START;                 !already set
               fault(4) %IF pending # 0
               %RETURN
            %FINISH
            dict(w+2) <- dict(w+2)!bit %IF pending # 0
            set const(n)
            op('_', tag(x)_index)
         %FINISH %ELSE %START
            fault(12)
         %FINISH
         access = 1
      %END

      %ROUTINE call
         %RECORD(tagfm)%NAME T;      !IMP77:
         t == tag(x)
         op('@', t_index)
         access = 0 %IF t_flags&closed # 0;         !never comes back
         put('E') %IF t_app = 0;             !no parameters
      %END

      %ROUTINE pop def
         set const(pstack(pending));  pending = pending-1
      %END

      %ROUTINE pop lit
         %IF pending = 0 %THEN lit = 0 %ELSE %START
            lit = pstack(pending);  pending = pending-1
         %FINISH
      %END


      %IF sstype < 0 %START;                       !executable statement
         %IF level = 0 %START;                     !outermost level
            fault(13);                             !*order
         %FINISH %ELSE %START
            %IF access = 0 %START
               access = 1;  fault(-1);                !only a warning
            %FINISH
         %FINISH
      %FINISH

      %IF diag&2 # 0 %START
         newline %IF sym # nl
         printstring("ss =")
         write(ss, 1)
         newline
         count = 5
         name = ""
      %FINISH

      next = ss
      pending = 0;  lmode = 0
      link = 0;  decs = 0
      defs = 0;  resln = 0;  done = 0
      ord = level
      ord = 1 %IF this >= 0;           !recordformat declarations
c(0):
top:  %IF next # link %START
         get next;  ->c(class)
c(*):debug("* Switch label not set: c(".itos(class,0).")"); %stop
      %FINISH

      !all done, tidy up declarations and jumps

      newline %IF diag&2 # 0 %AND count # 5

      %IF lmode&(loop!then!else) # 0 %START;    !pending labels and jumps
         op('B', label-1) %IF lmode&loop # 0;   !repeat
         def lab(label)   %IF lmode&then # 0;   !entry from then
         def lab(label-1) %IF lmode&else # 0;   !entry from else
      %FINISH

      %RETURN %IF decs = 0
      atom1 = error %AND %RETURN %IF atom1 # 0;      !%INTEGERROUTINE
      order = ord
      decl = decl&(\15)+decmap(decl&15);           !construct declarator flags
      atom1 = atoms(decl&15);                      !generate class
      %IF otype # 0 %START;                  !own, const etc.
         atom1 = atom1+1 %IF atom1 # proc
         %IF otype = 2 %START;               !const
            n = decl&15
            %if n&1 # 0 %start
               decl = decl!prot
               decl = decl!const bit %IF decl&2_1111111 = iform
            %finish
         %else
            decl = decl!own bit
         %FINISH
      %FINISH
      sstype = 1 %IF sstype = 0 %AND atom1 = proc
      atom1 = atom1+1 %IF decl&spec # 0;             !onto spec variant
      ocount = 0 %AND cont = '+' %IF atom1 = 5;      !own array
      %IF anyform(decl&15) = 0 %START;               !check meaningful
         %IF decl>>4&7 = record %START
            this = fdef %IF tag(fdef)_flags&spec # 0
            atom1 = error+21 %IF fdef = this;        !*context for format
         %FINISH
         atom1 = error+10 %IF fdef = 0;              !*size
      %FINISH
      %RETURN

atop:   access = 0;  ->top

! declarators

c(88):                                                !rtype
c(28): decl = x&(\7);                                 !stype
       fdef = x&7;                                    !precision
       fdef = reals ln %IF x&2_1110001 = real<<4+1;  !convert to long
       decs = 1;  ->top
c(34):                                                !own
c(35): otype = x;  ord = 1;  ->top;                   !external
c(152):decl = decl+x<<1;  ->top;                      !xname
c(31):                                                !proc
c(32): spec mode = level+1;                           !fn/map
       decl = decl!prot %IF x = 9;                    !function
c(29): ord = 1;                                       !array
       dim = 0
c(30): decl = decl+x;                                 !name
       decs = 1
       ->top
c(27): lit = 0;                                       ! arrayd
       %IF pending # 0 %START
          pop lit
          %UNLESS 0<lit<=dim limit %START
             atom1 = error + 11;  %RETURN
          %FINISH
       %FINISH
       dim = lit
       decl = decl + x;  decs = 1
       -> top
c(37): x = x!subname;                                 !record
c(36): lit = 0;                                       !string
       %IF pending # 0 %START
         pop lit
          %UNLESS 0 < lit <= 255 %START;              !max length wrong
             atom1 = error+10;  %RETURN
          %FINISH
       %FINISH
       fdef = lit;                                    !format or length
c(33): decl = x;                                      !switch
       decs = 1
       ->top
c(39): decl = decl!spec;                              !spec
       ocount = -1;                                   !no initialisation
       spec mode = -1
       ->top
c(38): decl = 64+4;                                   !recordformat (spec)
       order = 1
       atom1 = x
       decl = decl!spec %if atom1 = 12;               !formatspec
       fdef = tmax+1;                                 !format tag
       %return
c(175):id = id+1;  tag(x)_index = id;  %return;       !FSID
c(41): decs = 1;  decl = x!spec;  ->top;              !label
c(133):recid = 0;  rbase = tmin-1;                    !fname
       this = x
       fm base = fdef;  format list = tmin
       def(this);                      ->top
c(148):fdef = 0 %AND ->top %IF next = 0;              !reclb
       get next;                                      !skip name
       fdef = x
       ->top
c(127):put('}');  ->top;                              !%POUT
c(126):put('{');  ->top;                              !%PIN

c(174):set bp;                                        !rangerb
c(171):                                               !fmlb
c(172):                                               !fmrb
c(173):put('~');  put(class-171+'A');  ->top;
        !fmor
c(168):rbase = -rbase;                                !orrb
       sstype = 0;  spec mode = 0

c(147):search base = 0;                               !recrb
       tag(this)_app = tmin
       tag(this)_format = rbase
       ->top

c(45):put('U') %IF x = 36;  ->top;                    !sign
c(46):put('\');  ->top;                               !uop
c(47):                                                !mod
c(48):                                                !dot
c(42):                                                !op1
c(43):                                                !op2
c(44):put(operator(x));  ->top;                       !op3

!conditions & jumps

      %ROUTINE push(%INTEGER x)
         %IF cnest(cp)&2 # x %START
            cnest(cp) = cnest(cp)!1;  x = x+4
         %FINISH
         clab = clab+1 %IF cnest(cp)&1 # 0
         cnest(cp+1) = x;  cp = cp+1
      %END

      %ROUTINE pop label(%INTEGER mode)
         lmode = dict(dmin)
         %IF lmode < 0 %OR lmode&1 # mode %START
            fault(mode+8)
         %FINISH %ELSE %START
            dmin = dmin+1;  label = label-3
         %FINISH
      %END

c(56):                                         !and
c(57):push(x);  ->top;                         !or
c(58):cnest(cp) = cnest(cp)!!2;  ->top;        !not

c(138):x = 128+32+16+4;                        !csep: treat like %WHILE
c(59):                                         !while
c(60):%IF class = 138 %THEN op('f', label-1) %C
                      %ELSE def lab(label-1);  !until
c(166):                                        !runtil
c(62):lmode = (lmode&(else!loop)) !(x>>3);     !cword
      clab = label;  cp = 1;  cnest(1) = x&7
      ->top
c(72):pop label(0);                            !repeat
      def lab(label+1) %IF lmode&32 # 0;  ->atop
c(69):pop label(1);               ->top;       !finish
c(163):                                        !xelse
c(70):pop label(1);                            !finish else ...
      fault(7) %IF lmode&3 = 3;                !dangling else
c(68):lmode = (lmode&else)!3;                  !...else...
      %IF access # 0 %START
         op('F', label-1);  lmode = else!3
      %FINISH
      def lab(label)
      ->top %IF next # 0

c(120):                                        !%MSTART
c(67):                                         !start
c(71):                                         !cycle
stcy: def lab(label-1) %AND lmode = loop %IF lmode = 0;!cycle
      dmin = dmin-1;  abandon(3) %IF dmin <= dmax
      dict(dmin) = lmode
      label = label+3
      %RETURN

c(64):fault(13) %IF dict(dmin) >= 0 %OR inhibit # 0;  !on event
      inhibit = 1
      last array = tmax-1
      n = 0
      n = 16_FFFF %IF pending = 0;      !* = all events
      %WHILE pending > 0 %CYCLE
         pop lit;  fault(10) %IF lit&(\15) # 0;!too big
         j = 1<<lit
         dubious = 1 %IF n&j # 0
         n = n!j;                              !construct bit mask
      %REPEAT
      op('o', n);  op(',', label)
      lmode = then!1;  ->stcy


c(104):op('J', tag(x)_index);                  !l
       inhibit = 1;            ->atop
c(149):stats = stats-1;                        !lab
       access = 1;  inhibit = 1
       fault(13) %IF x < last array;           !jump round array dec
       op('L', tag(x)_index);  ->top

c(63):j = dmin;  l = label-3;                  !exit, continue
      %CYCLE
         fault(7) %AND ->top %IF dict(j) < 0
         %EXIT %IF dict(j)&1 = 0
         j = j+1;  l = l-3
      %REPEAT
      l = l+1 %IF x = 32;                      !continue
      op('F', l)
      dict(j) = dict(j)!x;                     !show given
      ->atop

c(50):put('C');  ->cop;                        !acomp

c(49):
       %IF next # 0 %START;                     !comparator
          put('"');  push(0);                  !double sided
       %FINISH %ELSE %START
          put('?')
       %FINISH

cop:   x = x!!1 %IF cnest(cp)&2 # 0;           !invert the condition
       j = cp;  l = clab
       %WHILE cnest(j)&4 = 0 %CYCLE
          j = j-1;  l = l-cnest(j)&1
       %REPEAT
       op(cc(x), l)
       def lab(clab+1) %IF cnest(cp)&1 # 0
       cp = cp-1
       clab = clab-cnest(cp)&1
       ->top

c(78):                                              !fresult
c(79):                                              !mresult
c(80):   open = 0;                                  !return, true, false
c(82):   access = 0;                                !stop
c(89):                                              !addop
c(81):   put(x);  ->top;                            !monitor

c(65):   pop lit;  op('e', lit);  ->atop;  !signal

c(51):   put('S');            ->top;                !eq
c(53):   put('j');            ->top;                !jam transfer
c(52):   put('Z');            ->top;                !eqeq

c(74):%IF level = 0 %START;                         !begin
         %IF progmode <= 0 %THEN progmode = 1 %ELSE fault(7)
         {Permit BEGIN after external defs}
      %FINISH
      spec mode = level+1
      block x = 0
      put('H');  %RETURN
c(77):perm = 0;  lines = 0;  stats = 0;             !endofperm
debug("close input    {input stream=".itos(input stream,0)."}")
      close input
debug("select input(source=".itos(source,0).")")
      select input(source);
      sym = nl
      list = list-1
      list = list -1 %if command & listbit # 0
      tbase = tmax;  tstart = tmax
      %RETURN
c(76):%IF include # 0 %AND x = 0 %START;            !end of ...
         lines = include;  sstype =  0;             !include
debug("close input    {input stream=".itos(input stream,0)."}")
         close input
         list = include list
         include = 0;
debug("select input(source=".itos(source,0).")")
	 select input(source);
	 sym = nl;
	 %RETURN
      %FINISH
      ss = -1;                                      !prog/file
c(75):compile end(x);  %RETURN;                     !%END

c(85):%IF x=0 %THEN control=lit %ELSE %START;     !control
         diag = lit&16_3FFF %IF lit>>14&3 = 1
      %FINISH
      op('z'-x, lit)
      ->top
c(83):list = list+x-2;   ->top;                     !%LIST/%ENDOFLIST
c(84):reals ln = x;      ->top;                     !%REALS long/normal
c(86):%IF include # 0 %START;                       !include "file"
         fault(7);  %RETURN
      %FINISH
      get next;                                  !sconst
      include file = string(x-16_4000+stbase)
      open input(3, include file)
      include = lines;  lines = 0
      include list = list
debug("select input(3)")
      select input(3);
      sym = nl
      ->top

c(154):dimension = dimension+1;                     !dbsep
       fault(11) %IF dimension = dim limit+1
       ->top
c(145):set bp;                       ->top;         !crb
c(146):set bp;                                      !rcrb
c(142):                                             !bplrb
       dimension = 1 %IF dimension = 0
       op('d', dimension);  op(',', defs)
       %IF class # 146 %START
          set subs(defs)
          last array = tmax-1
          fault(13) %IF dict(dmin) >= 0 %OR inhibit # 0 %OR level=0
       %FINISH
       dimension = 0;  defs = 0
       ->top
c(128):id = dupid;  ->top;                          !EDUP
c(130):block x = x
       op('F', 0) %IF decl&spec = 0 %AND level # 0; !jump round proc
c(125):dupid = id;                                  !%DUP
c(90): def(x);  ->top;                              !ident
c(131):                                             !cident
       %IF tag(x)_flags&(2_1111111+const bit) = iform+const bit %START
          tag(x)_format = lit
       %FINISH %ELSE %START
          set const(lit) %IF pending # 0
          def(x)
         put('A'); putlong(1)
       %FINISH
       cident = x
       ->top
c(124):dubious = 1 %IF tag(cident)_flags&prot # 0; !%DUBIOUS
       ->top
c(97):                                              !f
c(98):                                              !m
c(99):                                              !p
c(96): call;  ->top;                                !r

c(165):                                             !nlab
c(100):                                             !rp
c(101):                                             !fp
c(102):                                             !mp
c(103):                                             !pp
c(91):                                              !v
c(92):                                              !n
c(106):                                             !a
c(107):                                             !an
c(108):                                             !na
c(109):                                             !nan
      k = tag(x)_index
      %IF k < 0 %THEN op('n', -k) %ELSE op('@', k)
      ->top
c(121):set const(0);  ->top;                        !special for zero
c(167):put('G');  ->pstr;                           !aconst (alias)
c(const):                                           !const
       %IF x < 0 %START;                            !constinteger
          set const(tag(-x)_format);  ->top
       %FINISH
       %IF x&16_4000 # 0 %START;                    !strings
          put('''')
pstr:     x = x-16_4000+stbase
          k = byteinteger(x)
         putblock(k+1, byteinteger(x))
         -> top
       %FINISH
       %IF x&16_2000 # 0 %START;                    !real
          x = x-16_2000+stbase
          k = byteinteger(x)
          op('D', k);  put(',')
          k = k+x
          %CYCLE
             ->top %IF x = k
             x = x+1;  j = byteinteger(x)
             %IF j = '@' %START
                op('@', litpool(byteinteger(x+1)));  ->top
             %FINISH
             put(j)
          %REPEAT
       %FINISH
       set const(lit pool(x))
       ->top

c(137):put('i');               ->top;         !asep
c(141):put('a');               ->top;         !arb

!own arrays

c(132):ocount = ub-lb+1
       def(x);                               !oident
       dimension = 1;  set subs(1)
       %IF next = 0 %START;                  !no initialisation
          %IF ocount > 0 %start
            put('A'); putlong(ocount)
            %finish
          ocount = -1
       %FINISH %ELSE %START;                 !initialisation given
          get next
       %FINISH
       ->top
c(162):lit = ocount;  ->ins;                 !indef
c(143):pop lit;                              !orb
ins:   fault(10) %AND lit = 0 %IF lit < 0
       get next
       ->inst
c(139):                                      !osep (x=19)
c(153):lit = 1
inst:  pop def %IF pending # 0;              !ownt (x=0)
      put('A'); putlong(lit)
       ocount = ocount-lit
       %IF ocount >= 0 %START
          ->top %IF x # 0;      !more coming
          ocount = -1 %AND %RETURN %IF ocount = 0;  !all done
       %FINISH
       fault(11);  %RETURN

c(swit):op('W', tag(x)_index);  inhibit = 1;  ->atop
c(134):def(x);                               !swid
       n = ub-lb+1
       n = (n+15)>>4;                        !slots needed (includes zero)
       j = dmax;  dmax = dmax+n+2
       abandon(1) %IF dmax >= dmin
       tag(x)_format = j
       dict(j) = lb;  dict(j+1) = ub
       %CYCLE
          n = n-1
          ->top %IF n < 0
          j = j+1;  dict(j+1) = 0
       %REPEAT
c(151):stats = stats-1;                      !slab
       fault(7) %AND %RETURN %IF x < tbase
       %IF pending # 0 %START;               !explicit label
          def s lab(pstack(1))
       %FINISH %ELSE %START
          fault(4) %AND %RETURN %IF tag(x)_app # 0
          tag(x)_app = 1
          n = tag(x)_format
          %FOR j = dict(n), 1, dict(n+1) %CYCLE;   !imp77:
             def s lab(j);                         !imp77:
          %REPEAT;                                 !imp77:
       %FINISH
       inhibit = 1
       %RETURN

c(140):put('p');             ->top;          !psep
c(144):put('p');  put('E');  ->top;          !prb

!constant expressions

c(155):                                      !pconst
       %IF x < 0 %THEN lit = tag(-x)_format %ELSE lit = lit pool(x)
       pending = pending+1;     pstack(pending) = lit;  ->top
c(156):lit = pstack(pending);  lit = -lit %IF lit < 0
                                pstack(pending) = lit;  ->top;  !cmod
c(157):-> top %if X#36          { JGH fix to %const %integer X = +1 => -1 bug }
       lit = -pstack(pending);  pstack(pending) = lit;  ->top;  !csign
c(158):lit = \pstack(pending);  pstack(pending) = lit;  ->top;  !cuop
c(159):                                      !cop1
c(160):                                      !cop2
c(161):pending = pending-1;                  !cop3
       lit2 = pstack(pending+1);  lit = pstack(pending)
       ->litop(x>>2)
litop(*):debug("* Switch label not set: litop(".itos(x>>2,0).") {x=".itos(x,2)."}"); %stop
litop(10):lit = lit*lit2;   ->setl
litop(12):
litop(3):n = 1;                              !lit = lit\\lit2
         fault(10) %IF lit2 < 0
         %WHILE lit2 > 0 %CYCLE
            lit2 = lit2-1
            n = n*lit
         %REPEAT
         lit = n;           ->setl
litop(1):lit = lit<<lit2;   ->setl
litop(2):lit = lit>>lit2;   ->setl
litop(5):lit = lit&lit2;    ->setl
litop(11):
litop(4):%IF lit2 = 0 %THEN fault(10) %ELSE lit = lit//lit2
                            ->setl
litop(8):lit = lit+lit2;    ->setl
litop(9):lit = lit-lit2;    ->setl
litop(6):lit = lit!lit2;    ->setl
litop(7):lit = lit!!lit2

setl: pstack(pending) = lit;  ->top

c(170):            !option string
   put('~'); put('D')
   ->pstr

!string resolution

c(135):resln = 2;         ->top;           !dotl
c(136):resln = resln+1;   ->top;           !dotr
c(55): op('r', resln);    resln = 0; ->top;           !resop
c(164):op('r', resln+4);  resln = 0;         !cresop
c(122):x = 6;            ->cop;            !%PRED
c(87):set const(pstack(1));            !mass
      put('P');  ->top
   %END

%END;                                      !of compile block

debug("ENTERED PASS1  object tank=".itos(object tank,0)." *************")

   %ON 9 %START
debug("[3]%ON 9 %START:")
      abandon(5)
   %FINISH

   selectoutput(listing)                               ;!!!!!!!!!!!!!!!! THIS FAILS
!debug("A: object tank=".itos(object tank,0))
   %if command & list bit # 0 %start
      printstring("
      Computer Science VAX-11 IMP77 Compiler.  Version 8.02

            Compiled on ".date." at ".time)
      newlines(2)
debug("select input(1)")
      select input(1)
      printstring("   Source file: ".infilename)
      newline;  newline
!debug("B: object tank=".itos(object tank,0))
   %finish
!debug("C: object tank=".itos(object tank,0))
debug("select input(prims=".itos(prims,0).")")
   select input(prims)
debug("select output tank(object tank=".itos(object tank,0).")")
   select output tank(object tank)
   tag(max tag) = 0;                       !%BEGIN defn
   tag(0) = 0;  tag(0)_flags = 7;          !%BEGIN tag!
   %FOR x = 0, 1, max names %CYCLE;   !imp77:
      hash(x) = 0;                    !imp77:
   %REPEAT;                           !imp77:
   include file = ""
   put('l'); putword(0)
   compile block(0, 0, max dict, 0, 0)
   %result = -faulty %IF faulty # 0;   !imp77: %ENDOFPROGRAM
   %result = stats
%end
%endoffile
