-- file Pass1T.Mesa rewritten by PGS,  8-Jan-80  9:40
-- file Pass1T.Mesa
-- syntax last modified by Satterthwaite, 10-Dec-79 12:30
-- rules  last modified by Satterthwaite, January 8, 1980  10:49 AM

DIRECTORY
  ComData: FROM "comdata"
    USING [
      definitionsOnly, nTypeCodes,
      idANY, idBOOLEAN, idCARDINAL, idCHARACTER, idINTEGER, idLOCK, idREAL],
  ParseTable: FROM "parsetable"
    USING [ActionEntry, Production, ProductionInfo, TSymbol, tokenID],
  P1: FROM "p1" USING [InputLoc, LockId],
  Symbols: FROM "symbols" USING [HTNull],
  Tree: FROM "tree" USING [Link, Map, NodeName, Null, NullId],
  TreeOps: FROM "treeops" USING [
      FreeTree, ListLength, MakeNode, ExtractTree, InsertTree,
      PopTree, PushTree, PushHash, PushList, PushLit, PushProperList, PushSe,
      PushNode, PushStringLit, SetAttr, SetInfo, TestTree, UpdateList];

Pass1T: PROGRAM
    IMPORTS
	P1, TreeOps,
	dataPtr: ComData
    EXPORTS P1 =
  BEGIN  -- parse tree building
  OPEN TreeOps;

 -- local data base (supplied by parser)

  v: DESCRIPTOR FOR ARRAY OF UNSPECIFIED;
  l: DESCRIPTOR FOR ARRAY OF CARDINAL;

  q: DESCRIPTOR FOR ARRAY OF ParseTable.ActionEntry;

  ProdData: TYPE = ARRAY ParseTable.Production OF ParseTable.ProductionInfo;
  prodData: POINTER TO ProdData;

 -- initialization/termination

  AssignDescriptors: PUBLIC PROCEDURE [
	qd: DESCRIPTOR FOR ARRAY OF ParseTable.ActionEntry,
	vd: DESCRIPTOR FOR ARRAY OF UNSPECIFIED,
	ld: DESCRIPTOR FOR ARRAY OF CARDINAL,
	pp: POINTER TO ProdData] =
    BEGIN
    q ← qd;  v ← vd;  l ← ld;  prodData ← pp;
    END;


 -- the interpretation rules

  LinkToSource: PROCEDURE [index: CARDINAL] = BEGIN SetInfo[l[index]] END;

  public: BOOLEAN;
  -- initialization
    init: BOOLEAN = FALSE;
    equate: BOOLEAN = TRUE;
  -- machine dependent segments
    machineDep: BOOLEAN;

  ProcessQueue: PUBLIC PROCEDURE [qI, top: CARDINAL] =
    BEGIN
    i: CARDINAL;
    vTop: UNSPECIFIED;
    sv1, sv2: Tree.Link;
    FOR i IN [0..qI)
      DO
      top ← top-q[i].tag.pLength+1;  vTop ← v[top];
      SELECT prodData[q[i].transition].rule FROM

       -- basic tree building
        0  => -- MODULE: ParseTable
              -- BINARY: MesaTab      INTERFACE: CBinary
	      -- GOAL:  goal

	      --TERMINALS:
	      --  id    num    lnum    string    lstring
	      --  char    ,    ;    :   ..
	      --  =>   ←   =   #   <
	      --  >   <=   >=   ~   +
	      --  -   *   /   ↑   .
	      --  @   !   '|   INTEGER   CARDINAL
	      --  CHARACTER   BOOLEAN   REAL   RECORD   POINTER REF
	      --  ARRAY   DESCRIPTOR   PROCEDURE   PROC  PORT   SIGNAL
	      --  ERROR   PROCESS   PROGRAM   MONITOR   RELATIVE
	      --  LONG   TYPE   FRAME   TO   ORDERED
	      --  BASE   OF   PACKED   RETURNS   MONITORED
	      --  OVERLAID   COMPUTED   MACHINE   DEPENDENT   DIRECTORY
	      --  DEFINITIONS   IMPORTS   EXPORTS   SHARES   RESIDENT
	      --  LOCKS   USING   PUBLIC   PRIVATE   READONLY
	      --  ENTRY   INTERNAL   INLINE   CODE   ABS
	      --  ALL   AND   MAX   MIN   MOD
	      --  NOT   OR   LENGTH   NEW   START
	      --  FORK   JOIN   LOOPHOLE   SIZE   FIRST
	      --  LAST   NULL   IF   THEN   ELSE
	      --  WITH   FROM   FOR   DECREASING  IN
	      --  THROUGH  UNTIL  WHILE  REPEAT  FINISHED
	      --  RETURN  EXIT  LOOP  GOTO  GO
	      --  WAIT  RESTART  NOTIFY  BROADCAST  STOP
	      --  RESUME  CONTINUE  RETRY  TRANSFER  STATE
	      --  OPEN  ENABLE  ANY  EXITS  )
	      --  ]  }  END  ENDLOOP  ENDCASE
	      --  (  [  {  BEGIN  DO
	      --  SELECT

	      --ALIASES:
	      --  id       tokenID
	      --  num      tokenNUM
	      --  lnum     tokenLNUM
	      --  string   tokenSTR
	      --  lstring  tokenLSTR
	      --  char     tokenCHAR
	      --  -        tokenMINUS
	      --  .        tokenDOT
	      --  ..       tokenDOTS
	      --  =        tokenEQUAL
	      --  =>       tokenARROW
	      --  <        tokenLESS
	      --  <=       tokenLE
	      --  >        tokenGREATER
	      --  >=       tokenGE
	      --  .        InitialSymbol

	      --PRODUCTIONS:

              -- goal           ::= . unit . 
	      -- goal           ::= . unit .. 
	  NULL;
        1  => -- unit           ::= directory module 
	  BEGIN
	  PushNode[unit,2];  LinkToSource[top];
	  END;
        2  => -- directory      ::= DIRECTORY includelist ;
	  PushList[v[top+1]];
        3  => -- includeitem    ::= id : FROM string using
	  BEGIN
	  PushStringLit[v[top+3]];  PushHash[v[top]];
	  PushNode[diritem,-3];  LinkToSource[top];
	  END;
        4  => -- using          ::= USING [ ]
	  PushProperList[0];
        5  => -- module         ::= id : classhead block 
	      -- module         ::= id : defhead defbody 
	  BEGIN
	  IF ~v[top+3] THEN InsertTree[Tree.Null, 2];
	  PushTree[Tree.Null];
	  PushNode[body,4];
	  SetAttr[1,FALSE];  SetAttr[2,FALSE];  SetAttr[3,FALSE];
	  PushTree[ExtractTree[3]];  PushHash[v[top]];
	  PushNode[decl,-3];  LinkToSource[top];
	  SetAttr[1,equate];  SetAttr[2,TRUE];  SetAttr[3,FALSE];
	  PushNode[module,5];  LinkToSource[top];  SetAttr[1, v[top+2]];
	  END;
        6  => -- classhead       ::= resident PROGRAM arguments interface = public 
	  BEGIN
	  dataPtr.definitionsOnly ← FALSE;
	  PushTree[ExtractTree[5]];  PushTree[ExtractTree[5]];
	  PushNode[programTC,2];
	  PushTree[Tree.Null];  vTop ← v[top];  machineDep ← FALSE;
	  END;
        7  => -- classhead      ::= resident MONITOR arguments locks interface = public 
	  BEGIN
	  dataPtr.definitionsOnly ← FALSE;
	  sv1 ← ExtractTree[4];
	  PushTree[ExtractTree[5]];  PushTree[ExtractTree[5]];
	  PushNode[programTC,2];
	  IF sv1 # Tree.Null
	    THEN PushTree[sv1]
	    ELSE
	      BEGIN
	      PushHash[P1.LockId[]];  PushTree[Tree.Null];
	      PushNode[lambda,-2];  SetAttr[1,TRUE];  SetAttr[2,public];
	      END;
	  vTop ← v[top];  machineDep ← FALSE;
	  END;
        8  => -- resident       ::= RESIDENT 
	  BEGIN
	  public ← FALSE;  vTop ← TRUE;
	  END;
        9  => -- resident       ::= 
	  BEGIN
	  public ← FALSE;  vTop ← FALSE;  l[top] ← P1.InputLoc[];
	  END;
       10  => -- defhead        ::= definitions locks imports shares = public 
	  BEGIN
	  dataPtr.definitionsOnly ← TRUE;
	  sv1 ← ExtractTree[3];
	  sv2 ← PopTree[];  PushTree[Tree.Null];  PushTree[sv2];
	  PushNode[definitionTC,0];  PushTree[sv1];
	  vTop ← FALSE;  machineDep ← FALSE;
	  END;
       11  => -- definitions     ::= DEFINITIONS 
	  public ← TRUE;
       12  =>  -- defbody        ::= BEGIN open declist END 
               -- defbody        ::= { open declist } 
	  BEGIN
	  PushList[v[top+2]];  PushTree[Tree.Null];  vTop ← TRUE;
	  END;
       13  => -- locks          ::= LOCKS primary
	  BEGIN
	  PushTree[Tree.Null];   PushNode[lambda,-2];
	  SetAttr[1,FALSE];  SetAttr[2,FALSE];
	  END;
       14  => -- locks          ::= LOCKS primary USING id : typeexp
	  BEGIN
	  PushHash[v[top+3]];  InsertTree[Tree.Null,3];
	  PushNode[decl,-3];  LinkToSource[top+3];
	  SetAttr[1,FALSE];  SetAttr[2,FALSE];  SetAttr[3,FALSE];
	  PushNode[lambda,-2];  SetAttr[1,FALSE];  SetAttr[2,FALSE];
	  END;
       15  => -- moduleitem     ::= id 
	  BEGIN
	  PushHash[v[top]];  PushHash[v[top]];
	  PushNode[item,2];  SetAttr[1,FALSE];  LinkToSource[top];
	  END;
       16  => -- moduleitem     ::= id : id 
	  BEGIN
	  PushHash[v[top]];  PushHash[v[top+2]];
	  PushNode[item,2];  SetAttr[1,TRUE];  LinkToSource[top];
	  END;
       17  => -- declaration    ::= identlist public readonly entry typeexp initialization 
	  BEGIN
	  IF v[top+3] # Tree.NodeName[none] THEN PushNode[v[top+3],1];
	  PushNode[decl,3];  LinkToSource[top];
	  SetAttr[1,v[top+5]]; SetAttr[2,public]; public ← v[top+1];
	  SetAttr[3,v[top+2]];
	  END;
       18  => -- declaration    ::= identlist public TYPE = public typeexp default 
          BEGIN
	  public ← v[top+4];
	  PushNode[typedecl,3];  LinkToSource[top];
	  SetAttr[1,equate]; SetAttr[2,public]; public ← v[top+1];
	  SetAttr[3,FALSE];
	  END;
       19  => -- public         ::= PUBLIC
	  BEGIN
	  vTop ← public;  public ← TRUE;
	  END;
       20  => -- public         ::= PRIVATE
	  BEGIN
	  vTop ← public;  public ← FALSE;
	  END;
       21  => -- public         ::=
	  vTop ← public;
       22  => -- entry          ::= ENTRY
	  vTop ← Tree.NodeName[entry];
       23  => -- entry          ::= INTERNAL
	  vTop ← Tree.NodeName[internal];
       24  => -- entry          ::=
	  BEGIN
	  vTop ← Tree.NodeName[none];  l[top] ← P1.InputLoc[];
	  END;
       25  => -- idlist'        ::= id 
	      -- identlist'     ::= id : 
	  BEGIN
	  PushHash[v[top]];  vTop ← -1;
	  END;
       26  => -- idlist'        ::= id , idlist' 
	      -- identlist'     ::= id , identlist' 
	  BEGIN
	  PushHash[v[top]];  vTop ← v[top+2]-1;
	  END;
       27  => -- typeexp        ::= id 
	      -- range          ::= id
	  PushHash[v[top]];
       28  => -- typeid         ::= INTEGER 
	  PushSe[dataPtr.idINTEGER];
       29  => -- typeid         ::= CARDINAL 
	  PushSe[dataPtr.idCARDINAL];
       30  => -- typeid         ::= CHARACTER 
	  PushSe[dataPtr.idCHARACTER];
       31  => -- typeid         ::= BOOLEAN 
	  PushSe[dataPtr.idBOOLEAN];
       32  => -- typeid         ::= REAL 
	  PushSe[dataPtr.idREAL];
       33  => -- typeid         ::= id . id 
	  BEGIN
	  PushHash[v[top]];  PushHash[v[top+2]];
	  PushNode[dot,2];
	  END;
       34  => -- typeid         ::= id id 
	  BEGIN
	  PushHash[v[top+1]];  PushHash[v[top]];
	  PushNode[discrimTC,2];
	  END;
       35  => -- typeid         ::= id typeid 
	  BEGIN
	  PushHash[v[top]];  PushNode[discrimTC,2];
	  END;
       36  => -- typecons       ::= interval 
	  BEGIN
	  PushSe[dataPtr.idINTEGER];  PushNode[subrangeTC,-2];
	  END;
       37  => -- typecons       ::= id interval 
	      -- range          ::= id interval
	  BEGIN
	  PushHash[v[top]];  PushNode[subrangeTC,-2];
	  END;
       38  => -- typecons       ::= typeid interval 
	      -- range          ::= typeid interval
	  PushNode[subrangeTC,2];
       39  => -- typecons       ::= { idlist }
	  BEGIN
	  PushNode[enumeratedTC,1];  SetAttr[1,public];
	  END;
       40  => -- typecons       ::= monitored dependent RECORD reclist
	  BEGIN
	  IF ~v[top]
	    THEN PushNode[recordTC,1]
	    ELSE
	      BEGIN
	      sv1 ← PopTree[];  v[top+2] ← ListLength[sv1];
	      sv1 ← UpdateList[sv1, DetachItem];  sv1 ← FreeTree[sv1];
	      PushList[v[top+2]+1];  PushNode[monitoredTC,1];
	      END;
	  SetAttr[1,machineDep]; SetAttr[2,v[top+3]];
	  machineDep ← v[top+1];
	  END;
       41  => -- typecons       ::= ordered base pointertype
	  BEGIN
	  sv2 ← MakeNode[pointerTC,1];
	  sv1 ← PopTree[];
	  PushTree[sv2];
	  SetAttr[1,v[top]];  SetAttr[2,v[top+1]];  SetAttr[3,v[top+2]];
	  IF sv1 # Tree.Null
	    THEN  BEGIN  PushTree[sv1];  PushNode[subrangeTC,2]  END;
	  END;
       42  => -- typecons       ::= REF
	  BEGIN
	  PushSe[dataPtr.idANY];  PushNode[pointerTC,1];
	  SetAttr[1,FALSE];  SetAttr[2,FALSE];  SetAttr[3,FALSE];
	  PushNode[longTC,1];
	  END;
       43  => -- typecons       ::= REF readonly typeexp
	  BEGIN
	  PushNode[pointerTC,1];
	  SetAttr[1,FALSE];  SetAttr[2,FALSE];  SetAttr[3,v[top+1]];
	  PushNode[longTC,1];
	  END;
       44  => -- typecons       ::= array indextype OF typeexp
	  BEGIN
	  PushNode[arrayTC,2];  SetAttr[1,v[top]];
	  END;
       45  => -- typecons       ::= DESCRIPTOR FOR readonly typeexp
	  BEGIN
	  PushNode[arraydescTC,1];  SetAttr[3,v[top+2]];
	  END;
       46  => -- typecons       ::= transfermode arguments
	  PushNode[v[top],2];
       47  => -- typecons       ::= id RELATIVE typeexp
	  BEGIN
	  PushHash[v[top]];  PushNode[relativeTC,-2];
	  END;
       48  => -- typecons       ::= typeid RELATIVE typeexp
	  PushNode[relativeTC,2];
       49  => -- typecons       ::= LONG typeexp
	  PushNode[longTC,1];
       50  => -- typecons       ::= FRAME [ id ]
	  BEGIN
	  PushHash[v[top+2]];  PushNode[frameTC,1];
	  END;
       51  => -- interval       ::= [ bounds ] 
          PushNode[intCC,2];
       52  => -- interval       ::= [ bounds ) 
          PushNode[intCO,2];
       53  => -- interval       ::= ( bounds ] 
          PushNode[intOC,2];
       54  => -- interval       ::= ( bounds ) 
          PushNode[intOO,2];
       55  => -- monitored      ::= MONITORED
	  BEGIN
	  PushHash[P1.LockId[]];  PushSe[dataPtr.idLOCK];
	  PushTree[Tree.Null];
	  PushNode[decl,3];  LinkToSource[top];
	  SetAttr[1,FALSE];  SetAttr[2,public];  SetAttr[3,FALSE];
	  vTop ← TRUE;
	  END;
       56  => -- dependent      ::= MACHINE DEPENDENT
	  BEGIN
	  vTop ← machineDep;  machineDep ← TRUE;
	  END;
       57  => -- dependent      ::=
	  vTop ← machineDep;
       58  => -- reclist        ::= [ pairlist ]
	      -- reclist        ::= [ typelist ]
	  BEGIN
	  PushList[v[top+1]];  vTop ← FALSE;
	  END;
       59  => -- reclist        ::= [ pairlist , variantpair ]
	  BEGIN
	  PushList[v[top+1]+1];  vTop ← TRUE;
	  END;
       60  => -- reclist        ::= [ variantpair ]
	  vTop ← TRUE;
       61  => -- reclist        ::= [ variantpart ]
	  BEGIN
	  AnonField[PopTree[],top];  vTop ← TRUE;
	  END;
       62  => -- pairitem       ::= identlist public typeexp default
	  BEGIN
	  PushNode[decl,3];  LinkToSource[top];
	  SetAttr[1,FALSE]; SetAttr[2,public]; public ← v[top+1];
	  SetAttr[3,FALSE];
	  END;
       63  => -- defaultopt     ::=
	  PushProperList[0];
       64  => -- defaultopt     ::= NULL
	  PushNode[void,0];
       65  => -- defaultopt     ::= exp '| NULL
	  BEGIN
	  PushNode[void,0];  PushList[2];
	  END;
       66  => -- variantpair    ::= identlist public variantpart
	  BEGIN
	  PushTree[Tree.Null];
	  PushNode[decl,3];  LinkToSource[top];
	  SetAttr[1,FALSE]; SetAttr[2,public]; public ← v[top+1];
	  SetAttr[3,FALSE];
	  END;
       67  => -- variantpart    ::= SELECT vcasehead FROM variantlist ENDCASE
              -- variantpart    ::= SELECT vcasehead FROM variantlist , ENDCASE
	  BEGIN
	  PushList[v[top+3]];  PushNode[unionTC,2];  SetAttr[1,v[top+1]];
	  END;
       68  => -- vcasehead      ::= id : public tagtype
	  BEGIN
	  PushHash[v[top]];  InsertTree[Tree.Null,3];
	  PushNode[decl,-3];  LinkToSource[top];
	  SetAttr[1,FALSE]; SetAttr[2,public]; public ← v[top+2];
	  SetAttr[3,FALSE];  vTop ← FALSE;
	  END;
       69  => -- vcasehead      ::= COMPUTED tagtype
	  BEGIN
	  AnonField[PopTree[],top];  vTop ← FALSE;
	  END;
       70  => -- vcasehead      ::= OVERLAID tagtype
	  BEGIN
	  AnonField[PopTree[],top];  vTop ← TRUE;
	  END;
       71  => -- tagtype        ::= *
	  PushNode[implicitTC,0];
       72  => -- variantitem    ::= idlist => subreclist
	  BEGIN
	  PushNode[variantTC,1];  SetAttr[1,machineDep];  SetAttr[2,v[top+2]];
	  PushTree[Tree.Null];  PushNode[typedecl,3];  LinkToSource[top];
	  SetAttr[1,TRUE]; SetAttr[2,public]; SetAttr[3,FALSE];
	  END;
       73  => -- subreclist     ::= NULL
              -- subreclist     ::= [ ]
	  BEGIN
	  PushTree[Tree.Null];  vTop ← FALSE;
	  END;
       74  => -- typelist       ::= typecons
	      -- typelist       ::= typeid
	  BEGIN
	  AnonField[PopTree[],top];
	  vTop ← -1;
	  END;
       75  => -- typelist       ::= id
	  BEGIN
	  PushHash[v[top]];  AnonField[PopTree[],top];
	  vTop ← -1;
	  END;
       76  => -- typelist       ::= typecons , typelist
	      -- typelist       ::= typeid , typelist
	  BEGIN
	  AnonField[ExtractTree[-(v[top+2]-1)],top];
	  vTop ← v[top+2]-1;
	  END;
       77  => -- typelist       ::= id , typelist
	  BEGIN
	  PushHash[v[top]];  AnonField[PopTree[],top];
	  vTop ← v[top+2]-1;
	  END;
       78  => -- pointertype    ::= pointerprefix
	  BEGIN
	  PushSe[dataPtr.idANY];  vTop ← FALSE;
	  END;
       79  => -- pointertype    ::= pointerprefix TO readonly typeexp
	  vTop ← v[top+2];
       80  => -- transfermode   ::= PROCEDURE
              -- transfermode   ::= PROC
	  vTop ← Tree.NodeName[procTC];
       81  => -- transfermode   ::= PORT
	  vTop ← Tree.NodeName[portTC];
       82  => -- transfermode   ::= SIGNAL
	  vTop ← Tree.NodeName[signalTC];
       83  => -- transfermode   ::= ERROR
	  vTop ← Tree.NodeName[errorTC];
       84  => -- transfermode   ::= PROCESS
	  vTop ← Tree.NodeName[processTC];
       85  => -- transfermode   ::= PROGRAM
	  vTop ← Tree.NodeName[programTC];
       86  => -- initialization ::=
	  BEGIN
	  PushTree[Tree.Null];  vTop ← FALSE;
	  END;
       87  => -- initvalue      ::= procaccess inline block
	  BEGIN
	  IF ~v[top+2] THEN  InsertTree[Tree.Null,2];
	  PushTree[Tree.Null];
	  PushNode[body,4];  SetAttr[1,FALSE];  SetAttr[2,FALSE];
	  SetAttr[3,v[top+1]];
	  public ← v[top];
	  END;
       88  => -- initvalue      ::= CODE
	  PushNode[signalinit,0];
       89  => -- initvalue      ::= MACHINE CODE BEGIN codelist END
	  BEGIN
	  PushProperList[v[top+3]];  PushNode[inline,1];
	  END;
       90  => -- codelist       ::= orderlist
	  BEGIN
	  PushList[v[top]];  vTop ← 1;
	  END;
       91  => -- codelist       ::= codelist ; orderlist
	  BEGIN
	  PushList[v[top+2]];  vTop ← v[top]+1;
	  END;
       92  => -- procaccess     ::=
	  BEGIN
	  vTop ← public;  public ← FALSE;
	  END;

       93  => -- statement      ::= lhs
	  BEGIN
	  sv1 ← PopTree[];  PushTree[sv1];
	  IF ~TestTree[sv1,apply]
	    THEN  BEGIN  PushTree[Tree.Null];  PushNode[apply,2]  END;
	  LinkToSource[top];
	  END;
       94  => -- statement      ::= lhs ← exp 
	  BEGIN
	  PushNode[assign,2];  LinkToSource[top];
	  END;
       95  => -- statement      ::= [ explist ] ← exp 
	  BEGIN
	  PushNode[extract,2];  LinkToSource[top];
	  END;
       96  => -- statement      ::= block 
	  BEGIN
	  IF v[top] THEN BEGIN  PushNode[block,2];  LinkToSource[top]  END;
	  sv1 ← ExtractTree[2];
	  IF sv1 # Tree.Null
	    THEN
	      BEGIN
	      PushTree[sv1];  PushNode[open,-2];  LinkToSource[top];
	      END;
	  END;
       97  => -- statement      ::= IF exp THEN statement elsepart 
	  BEGIN
	  PushNode[if,3];  LinkToSource[top];
	  END;
       98  => -- statement      ::= casehead casestmtlist ENDCASE otherpart
              -- statement      ::= casehead casestmtlist ; ENDCASE otherpart
	  BEGIN
	  sv1 ← PopTree[];  PushProperList[v[top+1]];  PushTree[sv1];
	  IF v[top] THEN PushNode[bind,4] ELSE PushNode[case,3];
	  LinkToSource[top];
	  END;
       99  => -- statement      ::= forclause dotest dohead doexit ENDLOOP 
	  BEGIN
	  PushNode[do,6];  LinkToSource[top];
	  END;
      100  => -- statement      ::= EXIT 
	  BEGIN
	  PushNode[exit,0];  LinkToSource[top];
	  END;
      101  => -- statement      ::= LOOP 
	  BEGIN
	  PushNode[loop,0];  LinkToSource[top];
	  END;
      102  => -- statement      ::= GOTO id 
	  BEGIN
	  PushHash[v[top+1]];  PushNode[goto,1];
	  LinkToSource[top];
	  END;
      103  => -- statement      ::= GO TO id 
	  BEGIN
	  PushHash[v[top+2]];  PushNode[goto,1];
	  LinkToSource[top];
	  END;
      104  => -- statement      ::= RETURN optargs
	  BEGIN
	  PushNode[return,1];  LinkToSource[top];
	  END;
      105  => -- statement      ::= transfer lhs
	  BEGIN
	  PushNode[v[top],1];  LinkToSource[top];
	  END;
      106  => -- statement      ::= WAIT lhs
	  BEGIN
	  PushNode[wait,1];  LinkToSource[top];
	  END;
      107  => -- statement      ::= ERROR
	  BEGIN
	  PushNode[syserror,0];  LinkToSource[top];
	  END;
      108  => -- statement      ::= STOP
	  BEGIN
	  PushTree[Tree.Null];  PushNode[stop,1];  LinkToSource[top];
	  END;
      109  => -- statement      ::= NULL
	  BEGIN
	  PushNode[null,0];  LinkToSource[top];
	  END;
      110  => -- statement      ::= RESUME optargs
	  BEGIN
	  PushNode[resume,1];  LinkToSource[top];
	  END;
      111  => -- statement      ::= CONTINUE
	  BEGIN
	  PushNode[continue,0];  LinkToSource[top];
	  END;
      112  => -- statement      ::= RETRY
	  BEGIN
	  PushNode[retry,0];  LinkToSource[top];
	  END;
      113  => -- statement      ::= lhs ← STATE
	  BEGIN
	  PushNode[dst,1];  LinkToSource[top];
	  END;
      114  => -- block          ::= BEGIN blockhead END 
	      -- block          ::= { blockhead }
	  vTop ← v[top+1]; 
      115  => -- block          ::= BEGIN blockhead exits END
              -- block          ::= { blockhead exits }
	  BEGIN
	  IF v[top+1]
	    THEN
	      BEGIN
	      sv1 ← PopTree[];  PushNode[block,2];  LinkToSource[top];
	      PushTree[sv1];
	      END;
	  vTop ← FALSE;  PushNode[label,2];  LinkToSource[top];
	  END;
      116  => -- blockhead       ::= open enables declist statementlist
	  BEGIN
	  IF v[top+2] = 0
	    THEN  vTop ← FALSE
	    ELSE
	      BEGIN
	      sv1 ← PopTree[]; PushList[v[top+2]]; PushTree[sv1]; vTop ← TRUE;
	      END;
	  IF v[top+1]
	    THEN
	      BEGIN
	      IF vTop
		THEN  BEGIN  PushNode[block,2];  LinkToSource[top+2]  END;
	      PushNode[enable,2];  LinkToSource[top+1];  vTop ← FALSE;
	      END;
	  END;
      117  => -- open           ::= OPEN bindlist ;
	  PushList[v[top+1]];
      118  => -- binditem       ::= exp
	  BEGIN
	  PushTree[Tree.NullId];  PushNode[item,-2];  LinkToSource[top];
	  END;
      119  => -- binditem       ::= id : exp
	  BEGIN
	  PushHash[v[top]];  PushNode[item,-2];
	  LinkToSource[top];
	  END;
      120  => -- casestmtitem   ::= caselabel => statement
	      -- caseexpitem    ::= caselabel => exp
	      -- catchcase      ::= lhslist => statement
	  BEGIN
	  sv1 ← PopTree[];
	  PushList[v[top]];  PushTree[sv1];
	  PushNode[item,2];  LinkToSource[top];
	  END;
      121  => -- casetest       ::= optrelation 
	  BEGIN
	  PushTree[Tree.Null];  PushNode[v[top],-2];
	  END;
      122  => -- casetest       ::= exp 
	  BEGIN
	  PushTree[Tree.Null];  PushNode[relE,-2];
	  END;
      123  => -- forclause      ::= FOR id ← exp , exp 
	  BEGIN
	  sv1 ← PopTree[];  sv2 ← PopTree[];
	  PushHash[v[top+1]];  PushTree[sv2];  PushTree[sv1];
	  PushNode[forseq,3];
	  END;
      124  => -- forclause      ::= FOR id direction IN range 
	  BEGIN
	  InsertTree[Tree.Null,2]; PushHash[v[top+1]]; PushNode[v[top+2],-3];
	  END;
      125  => -- forclause      ::= THROUGH range
	  BEGIN
	  InsertTree[Tree.Null,2]; PushTree[Tree.Null]; PushNode[upthru,-3];
	  END;
      126  => -- direction      ::= DECREASING 
	  vTop ← Tree.NodeName[downthru];
      127  => -- direction      ::=  
	  vTop ← Tree.NodeName[upthru];
      128  => -- dotest         ::= UNTIL exp 
	  PushNode[not,1];
      129  => -- dohead         ::= DO open enables declist statementlist
	  BEGIN
	  IF v[top+3] # 0
	    THEN
	      BEGIN
	      sv1 ← PopTree[]; PushList[v[top+3]]; PushTree[sv1];
	      PushNode[block,2];  LinkToSource[top];
	      END;
	  IF v[top+2]
	    THEN
	      BEGIN
	      PushNode[enable,2];  LinkToSource[top+2];
	      END;
	  END;
      130  => -- doexit         ::=
	  BEGIN
	  PushTree[Tree.Null];  PushTree[Tree.Null];
	  END;
      131  => -- doexit         ::= REPEAT exitlist
	      -- doexit         ::= REPEAT exitlist ;
	  BEGIN
	  PushList[v[top+1]];  PushTree[Tree.Null];
	  END;
      132  => -- doexit         ::= REPEAT exitlist ; FINISHED => statement
	      -- doexit         ::= REPEAT exitlist ; FINISHED => statement ;
	  BEGIN
	  sv1 ← PopTree[];  PushList[v[top+1]];  PushTree[sv1];
	  END;
      133  => -- doexit         ::= REPEAT FINISHED => statement
	      -- doexit         ::= REPEAT FINISHED => statement ;
	  InsertTree[Tree.Null,2];
      134  => -- exititem       ::= idlist => statement
	  BEGIN
	  PushNode[item,2];  LinkToSource[top];
	  END;
      135  => -- enables        ::= ENABLE catchitem ;
	  BEGIN
	  sv1 ← PopTree[];
	  PushList[v[top+1]];  PushTree[sv1];  PushNode[catch,2];
	  vTop ← TRUE;
	  END;
      136  => -- enables        ::= ENABLE BEGIN catchlist END ;
	  BEGIN
	  sv1 ← PopTree[];
	  PushList[v[top+2]];  PushTree[sv1];  PushNode[catch,2];
	  vTop ← TRUE;
	  END;
      137  => -- enables        ::= ENABLE BEGIN catchhead END ;
	  BEGIN
	  PushList[v[top+2]];  PushTree[Tree.Null];  PushNode[catch,2];
	  vTop ← TRUE;
	  END;
      138  => -- catchlist      ::= catchhead catchitem
	  vTop ← v[top] + v[top+1];
      139  => -- catchitem      ::= catchcase
	  BEGIN
	  PushTree[Tree.Null];  vTop ← 1;
	  END;
      140  => -- statementlist  ::= statementlist' statement
	  PushList[v[top]+1];
      141  => -- transfer       ::= SIGNAL
	  vTop ← Tree.NodeName[signal];
      142  => -- transfer       ::= ERROR
	  vTop ← Tree.NodeName[error];
      143  => -- transfer       ::= RETURN WITH ERROR
	  vTop ← Tree.NodeName[xerror];
      144  => -- transfer       ::= START
	  vTop ← Tree.NodeName[start];
      145  => -- transfer       ::= RESTART
	  vTop ← Tree.NodeName[restart];
      146  => -- transfer       ::= JOIN
	  vTop ← Tree.NodeName[join];
      147  => -- transfer       ::= NOTIFY
	  vTop ← Tree.NodeName[notify];
      148  => -- transfer       ::= BROADCAST
	  vTop ← Tree.NodeName[broadcast];
      149  => -- transfer       ::= TRANSFER WITH
	  vTop ← Tree.NodeName[lst];
      150  => -- transfer       ::= RETURN WITH
	  vTop ← Tree.NodeName[lstf];

       -- expression processing
      151  => -- keyitem        ::= id : optexp
	  BEGIN
	  PushHash[v[top]];  PushNode[item,-2];
	  END; 
      152  => -- optexp         ::= NULL
              -- initvalue      ::= NULL
	  PushNode[void,0];
      153  => -- exp            ::= transferop lhs 
          PushNode[v[top],1];
      154  => -- exp            ::= IF exp THEN exp ELSE exp 
          PushNode[ifx,3];
      155  => -- exp            ::= casehead caseexplist ENDCASE => exp 
              -- exp            ::= casehead caseexplist , ENDCASE => exp 
	  BEGIN
	  sv1 ← PopTree[];
	  PushProperList[v[top+1]];  PushTree[sv1];
	  IF v[top] THEN PushNode[bindx,4] ELSE PushNode[casex,3];
	  LinkToSource[top];
	  END;
      156  => -- exp            ::= lhs ← exp 
          PushNode[assignx,2];
      157  => -- exp            ::= ERROR 
          PushNode[syserrorx,0];
      158  => -- disjunct       ::= disjunct OR conjunct 
          PushNode[or,2];
      159  => -- conjunct       ::= conjunct AND negation 
          PushNode[and,2];
      160  => -- negation       ::= not relation 
          PushNode[not,1];
      161  => -- relation       ::= sum optrelation 
          PushNode[v[top+1],2];
      162  => -- optrelation    ::= not relationtail 
          vTop ← Tree.NodeName[SELECT Tree.NodeName[v[top+1]] FROM
	    relE => relN,
	    relN => relE,
	    relL => relGE,
	    relLE => relG,
	    relG => relLE,
	    relGE => relL,
	    in => notin,
	    notin => in,
	    ENDCASE => v[top+1]];
      163  => -- relationtail   ::= IN range 
          vTop ← Tree.NodeName[in];
      164  => -- relop          ::= = 
          vTop ← Tree.NodeName[relE];
      165  => -- relop          ::= # 
          vTop ← Tree.NodeName[relN];
      166  => -- relop          ::= < 
          vTop ← Tree.NodeName[relL];
      167  => -- relop          ::= <= 
          vTop ← Tree.NodeName[relLE];
      168  => -- relop          ::= > 
          vTop ← Tree.NodeName[relG];
      169  => -- relop          ::= >= 
          vTop ← Tree.NodeName[relGE];
      170  => -- sum            ::= sum addop product 
          PushNode[v[top+1],2];
      171  => -- addop          ::= + 
          vTop ← Tree.NodeName[plus];
      172  => -- addop          ::= - 
          vTop ← Tree.NodeName[minus];
      173  => -- product        ::= product multop factor 
          PushNode[v[top+1],2];
      174  => -- multop         ::= * 
          vTop ← Tree.NodeName[times];
      175  => -- multop         ::= / 
          vTop ← Tree.NodeName[div];
      176  => -- multop         ::= MOD 
          vTop ← Tree.NodeName[mod];
      177  => -- factor         ::= - primary 
          PushNode[uminus,1];
      178  => -- primary        ::= num 
	  PushLit[v[top]];
      179  => -- primary        ::= lnum 
	  BEGIN
	  PushLit[v[top]];  PushNode[mwconst,1];
	  END;
      180  => -- primary        ::= char 
	  BEGIN
	  PushLit[v[top]];  PushNode[clit,1];
	  END;
      181  => -- primary        ::= string 
	  PushStringLit[v[top]];
      182  => -- primary        ::= lstring 
	  BEGIN
	  PushStringLit[v[top]];  PushNode[llit,1];
	  END;
      183  => -- primary 	::= [ explist ]
	  BEGIN
	  PushTree[Tree.Null];  PushNode[apply,-2];
	  END;
      184  => -- primary        ::= prefixop [ orderlist ]
	  BEGIN
	  PushList[v[top+2]];  PushNode[v[top],1];
	  END;
      185  => -- primary        ::= typeop [ typeexp ]
          PushNode[v[top],1];
      186  => -- primary        ::= INTEGER [ explist ] 
	  BEGIN
	  PushSe[dataPtr.idINTEGER];  PushNode[apply,-2];
	  END;
      187  => -- primary        ::= CARDINAL [ explist ] 
	  BEGIN
	  PushSe[dataPtr.idCARDINAL];  PushNode[apply,-2];
	  END;
      188  => -- primary        ::= @ lhs
	  PushNode[addr,1];
      189  => -- primary        ::= DESCRIPTOR [ desclist ]
	  PushNode[arraydesc,1];
      190  => -- lhs            ::= id 
	  PushHash[v[top]];
      191  => -- lhs            ::= LOOPHOLE [ exp ]
	  BEGIN
	  PushTree[Tree.Null]; PushNode[loophole,2];
	  END;
      192  => -- lhs            ::= LOOPHOLE [ exp , typeexp ]
	  PushNode[loophole,2];
      193  => -- qualifier      ::= [ explist ]
	  PushNode[apply,2];
      194  => -- qualifier      ::= [ explist ! catchlist ]
	  BEGIN
	  sv1 ← PopTree[];
	  PushList[v[top+3]];  PushTree[sv1];  PushNode[catch,2];
	  PushNode[apply,3];
	  END;
      195  => -- qualifier      ::= . id
	  BEGIN
	  PushHash[v[top+1]];  PushNode[dot,2];
	  END;
      196  => -- qualifier      ::= ↑
	  PushNode[uparrow,1];
      197  => -- transferop     ::= SIGNAL
	  vTop ← Tree.NodeName[signalx];
      198  => -- transferop     ::= ERROR
	  vTop ← Tree.NodeName[errorx];
      199  => -- transferop     ::= START
	  vTop ← Tree.NodeName[startx];
      200  => -- transferop     ::= JOIN
	  vTop ← Tree.NodeName[joinx];
      201  => -- transferop     ::= NEW 
          vTop ← Tree.NodeName[new];
      202  => -- transferop     ::= FORK
	  vTop ← Tree.NodeName[fork];
      203  => -- prefixop       ::= LONG 
          vTop ← Tree.NodeName[lengthen];
      204  => -- prefixop       ::= ABS 
          vTop ← Tree.NodeName[abs];
      205  => -- prefixop       ::= MIN 
          vTop ← Tree.NodeName[min];
      206  => -- prefixop       ::= MAX 
          vTop ← Tree.NodeName[max];
      207  => -- prefixop       ::= BASE
	  vTop ← Tree.NodeName[base];
      208  => -- prefixop       ::= LENGTH
	  vTop ← Tree.NodeName[length];
      209  => -- prefixop       ::= ALL
	  vTop ← Tree.NodeName[all];
      210  => -- typeop         ::= CODE
	  BEGIN
	  vTop ← Tree.NodeName[typecode];
	  dataPtr.nTypeCodes ← dataPtr.nTypeCodes + 1;
	  END;
      211  => -- typeop         ::= SIZE
	  vTop ← Tree.NodeName[size];
      212  => -- typeop         ::= FIRST
	  vTop ← Tree.NodeName[first];
      213  => -- typeop         ::= LAST
	  vTop ← Tree.NodeName[last];
      214  => -- desclist       ::= exp , exp
	  BEGIN
	  PushTree[Tree.Null];  PushList[3];
	  END;
      215  => -- desclist       ::= exp , exp , typeexp
	  PushList[3];
      216  => -- pointerprefix  ::= POINTER
	  BEGIN
	  PushTree[Tree.Null];  vTop ← 1;
	  END;
      217  => -- declist        ::= 
	      -- catchitem      ::= ANY => statement
	  vTop ← 0;
      218  => -- includelist    ::= includeitem
	      -- modulelist     ::= moduleitem
	      -- pairlist       ::= pairitem
	      -- variantlist    ::= variantitem
	      -- bindlist       ::= binditem
	      -- statementlist' ::= statement ; 
	      -- casestmtlist   ::= casestmtitem
	      -- caselabel      ::= casetest 
	      -- exitlist       ::= exititem
	      -- catchhead      ::= catchcase ;
	      -- lhslist        ::= lhs
	      -- orderlist      ::= optexp 
	      -- keylist        ::= keyitem 
	      -- caseexplist    ::= caseexpitem
	  vTop ← 1;
      219  => -- includelist    ::= includelist , includeitem
	      -- modulelist     ::= modulelist , moduleitem
	      -- declist        ::= declist declaration ; 
	      -- pairlist       ::= pairlist , pairitem
	      -- variantlist    ::= variantlist , variantitem
	      -- bindlist       ::= bindlist , binditem
	      -- statementlist' ::= statementlist'  statement ; 
	      -- casestmtlist   ::= casestmtlist ; casestmtitem
	      -- caselabel      ::= caselabel , casetest 
	      -- exitlist       ::= exitlist ; exititem
	      -- catchhead      ::= catchhead  catchcase ;
	      -- lhslist        ::= lhslist , lhs
	      -- orderlist      ::= orderlist , optexp 
	      -- keylist        ::= keylist , keyitem 
	      -- caseexplist	::= caseexplist , caseexpitem
	  vTop ← v[top]+1;
      220  => -- idlist         ::= idlist'
	      -- identlist      ::= identlist'
	      -- statementlist  ::= statementlist'
	      -- explist        ::= orderlist
	      -- explist        ::= keylist
	  PushList[v[top]];
      221  => -- imports        ::= IMPORTS modulelist
	      -- fieldlist      ::= [ pairlist ]
	      -- fieldlist      ::= [ typelist ]
	      -- exits          ::= EXITS exitlist
	      -- exits          ::= EXITS exitlist ;
	  PushList[v[top+1]];
      222  => -- array		::= ARRAY
	      -- initialization ::= ← initvalue
	      -- casehead       ::= SELECT exp FROM
	  vTop ← FALSE;
      223  => -- readonly       ::= READONLY
	      -- ordered        ::= ORDERED
	      -- base           ::= BASE
	      -- array		::= PACKED ARRAY
	      -- initialization ::= = initvalue
	      -- inline		::= INLINE
	      -- casehead       ::= WITH binditem SELECT optexp FROM
	  vTop ← TRUE;
      224  => -- readonly       ::=
	      -- monitored      ::=
	      -- ordered        ::=
	      -- base           ::=
	      -- inline		::=
	      -- enables        ::=
	  BEGIN
	  vTop ← FALSE;  l[top] ← P1.InputLoc[];
	  END;
      225  => -- using          ::= USING [ idlist ]
	      -- interface      ::= imports exports shares
	      -- exports        ::= EXPORTS idlist 
	      -- shares	        ::= SHARES idlist 
	      -- typeexp        ::= typeid 
	      -- typeexp        ::= typecons 
	      -- default        ::= ← defaultopt 
	      -- defaultopt     ::= exp 
	      -- tagtype        ::= typeexp 
	      -- subreclist     ::= reclist 
	      -- pointerprefix  ::= POINTER interval 
	      -- indextype      ::= typeexp 
	      -- arguments      ::= arglist returnlist 
	      -- arglist        ::= fieldlist 
	      -- returnlist     ::= RETURNS fieldlist 
	      -- initvalue      ::= exp 
	      -- elsepart       ::= ELSE statement 
	      -- otherpart      ::= => statement 
	      -- dotest         ::= WHILE exp 
	      -- catchlist      ::= catchitem 
	      -- statementlist  ::= statement 
	      -- optargs        ::= [ explist ] 
	      -- optexp         ::= exp 
	      -- exp            ::= disjunct 
	      -- disjunct       ::=C conjunct 
	      -- conjunct       ::=C negation 
	      -- negation       ::=C relation 
	      -- not            ::= ~ 
	      -- not            ::= NOT 
	      -- relation       ::=C sum 
	      -- optrelation    ::= relationtail 
	      -- relationtail   ::= relop sum 
	      -- range          ::= interval 
	      -- range          ::= typeid 
	      -- bounds         ::= exp .. exp 
	      -- sum            ::=C product 
	      -- product        ::=C factor 
	      -- factor         ::=C primary 
	      -- primary        ::=C lhs 
	      -- desclist       ::= exp 
	      -- lhs            ::= ( exp ) 
	      -- lhs            ::= lhs qualifier 
	  NULL;
      226  => -- directory      ::= 
	      -- using          ::= 
	      -- locks          ::= 
	      -- imports        ::= 
	      -- exports        ::= 
	      -- shares         ::= 
	      -- default        ::= 
	      -- open           ::=
	      -- arglist        ::= 
	      -- returnlist     ::= 
	      -- indextype      ::=
	      -- elsepart       ::=
	      -- otherpart      ::=
	      -- statementlist  ::= 
	      -- forclause      ::= 
	      -- dotest         ::= 
	      -- optargs        ::= 
	      -- optexp         ::=
	  BEGIN
	  PushTree[Tree.Null];  vTop ← 1;  l[top] ← P1.InputLoc[];
	  END;

       -- error or unimplemented
	ENDCASE =>  ERROR;

      v[top] ← vTop;
      ENDLOOP;
    END;

    DetachItem: Tree.Map =
      BEGIN
      PushTree[t];  RETURN [Tree.Null]
      END;


 -- shared processing routines

  AnonField: PROCEDURE [type: Tree.Link, top: CARDINAL] =
    BEGIN
    PushTree[Tree.NullId];  PushTree[type];  PushTree[Tree.Null];
    PushNode[decl,3];  LinkToSource[top];
    SetAttr[1,FALSE];  SetAttr[2,public];  SetAttr[3,FALSE];
    END;


 -- error recovery

  TokenValue: PUBLIC PROCEDURE [s: ParseTable.TSymbol] RETURNS [UNSPECIFIED] =
    BEGIN
    OPEN ParseTable;
    RETURN [SELECT s FROM
      tokenID => Symbols.HTNull,
      ENDCASE => 0]
    END;

  END.