-- file PackTreeBuild.mesa rewritten by PGS, 28-Sep-81 14:56
-- file PackTreeBuild.mesa rewritten by PGS,  2-Apr-81 17:18
-- file PackTreeBuild.mesa rewritten by PGS,  2-Apr-81 17:15
-- file PackTreeBuild.mesa rewritten by PGS,  3-Sep-80 18:31
-- grammar last edited by Lewis on  1-Apr-81 16:45:10
-- rules   last edited by Lewis on  2-Apr-81 17:17:34 

DIRECTORY
  P1: FROM "PackParseDefs",
  SymTabDefs USING [HTIndex, HTNull],
  ParseTable USING [ActionEntry, Production, ProductionInfo, Symbol, tokenID],
  Tree: FROM "PackTree" USING [Link, Null, NullProcs],
  TreeOps: FROM "PackTreeOps" USING [
    PopTree, PushTree, PushHash, PushList, PushNode, SetAttr, SetInfo];

PackTreeBuild: PROGRAM
    IMPORTS TreeOps
    EXPORTS Tree, P1 =
  BEGIN OPEN TreeOps;

  root: PUBLIC Tree.Link ← Tree.Null;  -- root of packaging description tree

  ProdData: TYPE = ARRAY ParseTable.Production OF ParseTable.ProductionInfo;

  -- 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: LONG POINTER TO ProdData;

  AssignDescriptors: PUBLIC PROC [
	qd: DESCRIPTOR FOR ARRAY OF ParseTable.ActionEntry,
	vd: DESCRIPTOR FOR ARRAY OF UNSPECIFIED,
	ld: DESCRIPTOR FOR ARRAY OF CARDINAL,
	pp: LONG POINTER TO ProdData] =
    {q ← qd;  v ← vd;  l ← ld;  proddata ← pp};


  -- the interpretation rules

  LinkToSource: PROC [index: CARDINAL] = INLINE {SetInfo[l[index]]};

  exceptMain: BOOLEAN;
  primaryComponentId: SymTabDefs.HTIndex;

  ProcessQueue: PUBLIC PROC [qI, top: CARDINAL] =
    BEGIN
    reductionRule: [0..377B];
    i: CARDINAL;
    save, save2: Tree.Link;
    vTop: UNSPECIFIED;
    FOR i IN [0 .. qI) DO
      top ← top-q[i].tag.pLength+1;  vTop ← v[top];
      reductionRule ← proddata[q[i].transition].rule;
      SELECT reductionRule FROM

        0  =>	--
	    --TYPE: ParseTable
	    --TABLE: ParseData    EXPORTS: SELF
	    --GOAL:  Goal

	    --TERMINALS:
	    --    id 	endOfFile     :     =
	    --    [	]	;
	    --    ,	.       {     }

	    --  SEGMENT	BEGIN	END	CODE    PACK    DISCARD
	    --  EXCEPT 	MAIN	OF      FRAME   MERGES

	    --ALIASES:
	    --  id         tokenID
	    --  .          InitialSymbol
	    --  endOfFile  TrueEndOfFile

	    --  PRODUCTIONS:

		-- Goal		     ::= . PackagingDesc 
          NULL;

        1  =>   -- PackagingDesc     ::= DescSeries endOfFile
          {PushList[v[top]];  root ← PopTree[];  PushTree[root]};

        2  =>	-- DescSeries        ::= DescItem ;
             	-- DescSeries        ::= DescItem .
          vTop ← 1;

        3  =>	-- DescSeries        ::= DescSeries DescItem ;
             	-- DescSeries        ::= DescSeries DescItem .
          vTop ← v[top]+1;

        4  =>	-- DescItem          ::= CodeSegment
                -- DescItem          ::= FramePack 
                -- DescItem          ::= Merge 
                -- DescItem          ::= MergeFramePack 
          NULL;

        5  =>	-- CodeSegment       ::= id : SEGMENT = SegmentBody 
          BEGIN
          save ← PopTree[];
	  PushHash[v[top]];  PushTree[save];  
          PushNode[codeSeg, 2];  LinkToSource[top];
          END;

        6  =>	-- SegmentBody       ::= { CodePackSeries }
              	-- SegmentBody       ::= BEGIN CodePackSeries END
          PushList[v[top+1]];

        7  =>	-- CodePackSeries    ::= CodePack
          vTop ← 1;

        8  =>	-- CodePackSeries    ::= CodePackSeries ; CodePack
          vTop ← v[top]+1;

        9  =>	-- CodePackSeries    ::= CodePackSeries ;
          NULL;          -- allows trailing ;

       10  =>   -- CodePack          ::= id : CODE PACK = CodePackBody
          BEGIN
          save ← PopTree[];
	  PushHash[v[top]];  PushTree[save];  PushTree[Tree.NullProcs];
          PushNode[codePack, 3];  SetAttr[1, exceptMain];  LinkToSource[top];
          END;

       11  =>   -- CodePack          ::= ComponentDesc
          BEGIN
          PushList[1];  save ← PopTree[];
	  PushHash[primaryComponentId];  PushTree[save];  PushTree[Tree.NullProcs];
          PushNode[unnamedCodePack, 3];  SetAttr[1, FALSE];  LinkToSource[top];
          END;

       12  =>   -- CodePack          ::= id : DISCARD CODE PACK = CodePackBody
          BEGIN
          save ← PopTree[];
	  PushHash[v[top]];  PushTree[save];  PushTree[Tree.NullProcs];
          PushNode[discardCodePack, 3];  SetAttr[1, exceptMain];  LinkToSource[top];
          END;

       13  =>   -- CodePackBody      ::= { ExceptMain CompSeries }
                -- CodePackBody      ::= BEGIN ExceptMain CompSeries END
          PushList[v[top+2]];

       14  =>   -- ExceptMain        ::= 
          exceptMain ← FALSE;

       15  =>   -- ExceptMain        ::= EXCEPT [ MAIN ] ;
          exceptMain ← TRUE;

       16  =>	-- CompSeries        ::= ComponentDesc 
          vTop ← 1;

       17  =>	-- CompSeries        ::= CompSeries ; ComponentDesc 
          vTop ← v[top]+1;

       18  =>	-- CompSeries        ::= CompSeries ;
          NULL;          -- allows trailing ;

       19  =>   -- ComponentDesc     ::= Component
          {PushNode[allComp, 1];  LinkToSource[top]};

       20  =>   -- ComponentDesc     ::= Component [ ItemList ]
          {PushList[v[top+2]];  PushNode[compItems, 2];  LinkToSource[top]};

       21  =>   -- ComponentDesc     ::= Component EXCEPT [ ItemList ]
          {PushList[v[top+3]];  PushNode[exceptItems, 2];  LinkToSource[top]};

       22  =>   -- ComponentDesc     ::= Component EXCEPT PackList
          {PushList[v[top+2]];  PushNode[exceptPacks, 2];  LinkToSource[top]};

       23  =>   -- ComponentDesc     ::= Component [ ItemList ] EXCEPT PackList
          BEGIN
          PushList[v[top+5]];  save ← PopTree[];
          PushList[v[top+2]];  PushTree[save];  
          PushNode[itemsExceptPacks, 3];  LinkToSource[top];
          END;

       24  =>   -- ComponentDesc     ::= Component EXCEPT PackList , [ ItemList ]
          BEGIN
          PushList[v[top+5]];  save ← PopTree[];
          PushList[v[top+2]];  PushTree[save];  
          PushNode[exceptPacksItems, 3];  LinkToSource[top]
          END;

       25  =>   -- ComponentDesc     ::= MAIN OF PackList
          {PushList[v[top+2]];  PushNode[mainProcs, 1];  LinkToSource[top]};

       26  =>   -- Component         ::= OptQualifiedId
          {PushList[v[top]];  PushNode[component, 1];  LinkToSource[top]};

       27  =>   -- OptQualifiedId    ::= id
          {PushHash[v[top]];  vTop ← 1;  primaryComponentId ← v[top]};

       28  =>   -- OptQualifiedId    ::= OptQualifiedId . id
          {PushHash[v[top+2]];  vTop ← v[top]+1;  primaryComponentId ← v[top+2]};

       29  =>   -- ItemList          ::= Item
          vTop ← 1;

       30  =>   -- ItemList          ::= ItemList , Item
          vTop ← v[top]+1;

       31  =>	-- Item              ::= MAIN 
          PushNode[main, 0];

       32  =>	-- Item              ::= id 
          PushHash[v[top]];

       33  =>   -- PackList          ::= id
          {PushHash[v[top]];  vTop ← 1};

       34  =>   -- PackList          ::= PackList , id
          {PushHash[v[top+2]];  vTop ← v[top]+1};

       35  =>	-- FramePack         ::= id : FRAME PACK = FramePackBody 
          BEGIN
          save ← PopTree[];
	  PushHash[v[top]];  PushTree[save];  
          PushNode[framePack, 2];  LinkToSource[top];
          END;

       36  =>	-- FramePackBody     ::= { CompSeries }
              	-- FramePackBody     ::= BEGIN CompSeries END
          PushList[v[top+1]];

       37  =>	-- Merge             ::= id : SEGMENT MERGES SegList = SegmentBody 
          BEGIN
          save ← PopTree[];  PushList[v[top+4]];  save2 ← PopTree[];
	  PushHash[v[top]];  PushTree[save];  PushTree[save2];  
          PushNode[merge, 3];  LinkToSource[top];  -- N.B. SegList is 3rd son
          END;

       38  =>	-- MergeFramePack    ::= id : FRAME PACK MERGES FpList 
          BEGIN
          PushList[v[top+5]];  save ← PopTree[];
	  PushHash[v[top]];  PushTree[save];  
          PushNode[mergeFP, 2];  LinkToSource[top];
          END;

       39  =>   -- SegList           ::= id
                -- FpList            ::= id
          {PushHash[v[top]];  vTop ← 1};

       40  =>   -- SegList           ::= SegList , id
                -- FpList            ::= FpList , id
          {PushHash[v[top+2]];  vTop ← v[top]+1};

       ENDCASE => ERROR;

      v[top] ← vTop;
      ENDLOOP;
    END;

  TokenValue: PUBLIC PROC [s: ParseTable.Symbol] RETURNS [UNSPECIFIED] =
    BEGIN
    RETURN[SELECT s FROM
      ParseTable.tokenID => SymTabDefs.HTNull,
      ENDCASE => 0];
    END;

  END.