-- file MobTreeBuild.mesa rewritten by NPGS, May 25, 1990 11:07:59 am PDT
-- Copyright Ó 1991 by Xerox Corporation. All rights reserved.
-- file MobTreeBuild.pgs
-- DO NOT CONVERT TO TIOGA! (PGS requires that comments be mesa-style.)
-- last edited by Satterthwaite on March 14, 1986 11:22:21 am PST
-- last edited by Lewis on 12-Mar-81 18:04:07
-- last edited by Maxwell on August 11, 1983 3:36 pm
-- Andy Litman May 11, 1988 5:27:57 pm PDT
-- JKF, May 25, 1990 10:15:28 am PDT

-- NPGS [defs: MobParseTable, grammar: CMesa] ¬ MobTreeBuild.pgs


DIRECTORY
 MobP1: TYPE USING [
  ActionStack, Index, LinkStack, Value, ValueStack, InputLoc, nullId, nullValue],
 MobParseTable: TYPE USING [ProdDataRef, Symbol, tokenID, Rule],
 MobTree: TYPE USING [Link, null],
 MobTreeOps: TYPE USING [
  PopTree, PushTree, PushHash, PushList, PushNode, SetAttr, SetInfo];

MobTreeBuild: PROGRAM
 IMPORTS MobP1, MobTreeOps
 EXPORTS MobP1 = {
 OPEN MobTreeOps;

 -- local data base (supplied by parser)

 v: MobP1.ValueStack;
 l: MobP1.LinkStack;
 q: MobP1.ActionStack;
 proddata: MobParseTable.ProdDataRef;

 AssignDescriptors: PUBLIC PROC[
  qd: MobP1.ActionStack, vd: MobP1.ValueStack, ld: MobP1.LinkStack,
  pp: MobParseTable.ProdDataRef] ~ {
  q ¬ qd; v ¬ vd; l ¬ ld; proddata ¬ pp};


 -- the interpretation rules

 LinkToSource: PROC[index: MobP1.Index] ~ INLINE {SetInfo[l[index]]};

 exportsALL: BOOL;

 LinkSpec: TYPE ~ {frame, defaultFrame, code, defaultCode};
 CodeLinks: TYPE ~ LinkSpec[$code .. $defaultCode];
 DefaultLinks: ARRAY LinkSpec OF LinkSpec ~ [
  $defaultFrame, $defaultFrame, $defaultCode, $defaultCode];
  
 linkSpec: LinkSpec ¬ $defaultFrame;
  
 SetLinkAttrs: PROC ~ {
  SetAttr[$codeLinks, (linkSpec IN CodeLinks)];
  SetAttr[$explicitLinkLoc, (linkSpec # DefaultLinks[linkSpec])]
  };


 ProcessQueue: PUBLIC PROC[qI, top: CARDINAL] ~ {
  FOR i: CARDINAL IN [0 .. qI) DO
   rule: MobParseTable.Rule;
   top ¬ top-q[i].tag.pLength+1;
   rule ¬ proddata[q[i].transition].rule;
   SELECT rule FROM
    < 18 => ProcessQueue1[top, rule];
    ENDCASE => ProcessQueue2[top, rule];
   ENDLOOP;
   };
  
 ProcessQueue1: PROC[top: CARDINAL, rule: MobParseTable.Rule] ~ {
  save: MobTree.Link;
  vTop: MobP1.Value;
  vTop ¬ v[top];
  SELECT rule FROM

0 => --
  --TYPE: MobParseTable EXPORTS: SELF
  --GOAL: goal

 --TERMINALS:
 -- id  str , ;
 -- : ¬ = ~
 -- ] [ } { .

 -- DIRECTORY FROM PACK CONFIGURATION CONFIG
 -- IMPORTS EXPORTS CONTROL BEGIN REQUESTS STATIC DYNAMIC
 -- END PLUS THEN LINKS CODE FRAME ALL

 --ALIASES:
 -- id tokenID
 -- str tokenSTR
 -- . initialSymbol

 -- PRODUCTIONS:

 -- goal   ::= . source
 NULL;

1 => -- source ::= directory packing init config .
  {PushNode[$source,3]; LinkToSource[top]};

2 => -- directory ::= DIRECTORY includelist ;
  PushList[v[top+1].s];

3 => -- includeitem ::= id : FROM str
  {
  PushHash[LOOPHOLE[v[top].s]]; PushHash[LOOPHOLE[v[top+3].s]];
  PushNode[$item,2];
  LinkToSource[top];
  };

4 => -- packing ::= packlist ;
  PushList[v[top].s];

5 => -- packlist ::= PACK idlist
  {PushList[v[top+1].s]; LinkToSource[top]; vTop ¬ [scalar[1]]};

6 => -- packlist ::= packlist ; PACK idlist
  {PushList[v[top+3].s]; LinkToSource[top]; vTop ¬ [scalar[v[top].s+1]]};

7 => -- init ::=
  {linkSpec ¬ $defaultFrame; exportsALL ¬ FALSE};

8 => -- config ::= id : CONFIG links imports exports statics dynamics control tilde body
  -- config ::= id : CONFIGURATION links imports exports statics dynamics control tilde body
  {
  save ¬ PopTree[];
  PushHash[LOOPHOLE[v[top].s]]; PushTree[save]; PushNode[$config,7];
  SetAttr[$exportsALL, exportsALL]; LinkToSource[top];
  linkSpec ¬ v[top+3].a; exportsALL ¬ v[top+5].a; -- restore old values
  };

9 => -- links ::=
  {vTop ¬ [short[linkSpec,0]]; linkSpec ¬ DefaultLinks[linkSpec]};

10 => -- links ::= LINKS : CODE
  {vTop ¬ [short[linkSpec,0]]; linkSpec ¬ $code};

11 => -- links ::= LINKS : FRAME
  {vTop ¬ [short[linkSpec,0]]; linkSpec ¬ $frame};

12 => -- imports ::= IMPORTS itemlist
  -- body ::= BEGIN statementlist END
  -- body ::= { statementlist }
  -- leftside ::= [ itemlist ]
  PushList[v[top+1].s];

13 => -- control ::= CONTROL idlist
  PushList[v[top+1].s];

14 => -- statement ::= leftside ¬ module
  {PushNode[$assign,2]; LinkToSource[top]};

15 => -- statement ::= leftside ¬ interface
  {PushNode[$assign,2]; LinkToSource[top]};

16 => -- statement ::= item links
  {
  SetLinkAttrs[];
  PushTree[MobTree.null]; PushNode[$module,2];
  SetLinkAttrs[]; LinkToSource[top];
  linkSpec ¬ v[top+1].a;
  };

17 => -- module ::= item [ ] links
  {
  SetLinkAttrs[];
  PushTree[MobTree.null]; PushNode[$module,2];
  SetLinkAttrs[]; LinkToSource[top];
  linkSpec ¬ v[top+3].a;
  };

 ENDCASE => ERROR;
 v[top] ¬ vTop;
 };

 ProcessQueue2: PROC[top: CARDINAL, rule: MobParseTable.Rule] ~ {
  save: MobTree.Link;
  vTop: MobP1.Value;
  vTop ¬ v[top];
  SELECT rule FROM

18 => -- module ::= item [ idlist ] links
  {
  PushList[v[top+2].s]; save ¬ PopTree[];
  SetLinkAttrs[];
  PushTree[save]; PushNode[$module,2];
  SetLinkAttrs[]; LinkToSource[top];
  linkSpec ¬ v[top+4].a;
  };

19 => -- interface ::= id
  PushHash[LOOPHOLE[v[top].s]];

20 => -- interface ::= interface THEN id
  {PushHash[LOOPHOLE[v[top+2].s]]; PushNode[$then,2]; LinkToSource[top]};

21 => -- interface ::= interface PLUS id
  {PushHash[LOOPHOLE[v[top+2].s]]; PushNode[$plus,2]; LinkToSource[top]};

22 => -- item ::= id
  {
  PushHash[LOOPHOLE[v[top].s]]; PushTree[MobTree.null]; PushNode[$item,2];
  LinkToSource[top];
  };

23 => -- item ::= id : id
  {
  PushHash[LOOPHOLE[v[top].s]]; PushHash[LOOPHOLE[v[top+2].s]];
  PushNode[$item,2];
  LinkToSource[top];
  };

24 => -- idlist ::= id
  -- strlist ::= str
  {PushHash[LOOPHOLE[v[top].s]]; vTop ¬ [scalar[1]]};

25 => -- idlist ::= idlist , id
  -- strlist ::= strlist , str
  {PushHash[LOOPHOLE[v[top+2].s]]; vTop ¬ [scalar[v[top].s+1]]};

26 => -- tilde  ::= ~
  -- tilde  ::= =
  -- statementlist ::= statementlist ;
  -- statement  ::= module
  -- statement  ::= config
  -- leftside  ::= item
  NULL;

27 => -- imports ::=
  -- statics ::=
  -- dynamics ::=
   -- control ::=
   -- directory ::=
   -- packing ::=
   {PushTree[MobTree.null]; l[top] ¬ MobP1.InputLoc[]};

28 => -- includelist ::= includeitem
  -- statementlist ::= statement
  -- itemlist ::= item
  vTop ¬ [scalar[1]];

29 => -- includelist ::= includelist , includeitem
  -- statementlist ::= statementlist ; statement
  -- itemlist ::= itemlist , item
  vTop ¬ [scalar[v[top].s+1]];

30 => -- exports ::= EXPORTS expinit exportlist
  {vTop ¬ v[top+1]; PushList[v[top+2].s]};
  
31 => -- exports ::=
  {PushTree[MobTree.null]; l[top] ¬ MobP1.InputLoc[]; vTop ¬ [short[exportsALL,0]]};
  
32 => -- expinit ::=
  {vTop ¬ [short[exportsALL,0]]; exportsALL ¬ FALSE};

33 => -- exportlist ::= item
  vTop ¬ [scalar[1]];

34 => -- exportlist ::= ALL
  {exportsALL ¬ TRUE; vTop ¬ [scalar[0]]};

35 => -- exportlist ::= exportlist , item
  vTop ¬ [scalar[v[top].s+1]];

36 => -- exportlist ::= exportlist , ALL
  {exportsALL ¬ TRUE; vTop ¬ v[top]};

37 => -- statics ::= STATIC REQUESTS strlist
  { PushList[v[top+2].s] };

38 => -- dynamics ::= DYNAMIC REQUESTS strlist
  { PushList[v[top+2].s] };

  ENDCASE => ERROR;

 v[top] ¬ vTop;
 };

 TokenValue: PUBLIC PROC[s: MobParseTable.Symbol] RETURNS[MobP1.Value] ~ {
  RETURN [SELECT s FROM
   MobParseTable.tokenID => MobP1.nullId,
   ENDCASE => MobP1.nullValue]
  };

 }.