-- file CtoSTreeBuildImpl.mesa rewritten by PGS,  5-Jul-83 12:57
-- last modified by Satterthwaite, August 11, 1983 2:31 pm

DIRECTORY
  Atom: TYPE USING [GetPName, MakeAtom],
  CtoSP1: TYPE --P1-- USING [
    ActionStack, LinkStack, TValue, ValueStack, nullTValue, Substr],
  CtoSParseTable: TYPE ParseTable USING [ActionEntry, ProdDataRef, TSymbol],
  Rope: TYPE USING [Cat],
  SMTree: TYPE Tree USING [Link],
  SMTypeCons: TYPE --TypeCons-- USING [
    TM, Domain, MkArrow, MkCrossReverse, MkCross2, MkDeclElem, MkDeclReverse,
    MkInterfaceType, MkStringType, PushLink, Range],
  SMOps: TYPE USING [MS];

CtoSTreeBuildImpl: CEDAR PROGRAM
    IMPORTS Atom, CtoSP1, Rope, SMTypeCons
    EXPORTS CtoSP1 ~ {
  -- converts Cedar source programs to SML values
  OPEN P1~~CtoSP1, ParseTable~~CtoSParseTable, Tree~~SMTree, TypeCons~~SMTypeCons;
  
 -- local data base (supplied by parser)

  v: P1.ValueStack;
  l: P1.LinkStack;
  q: P1.ActionStack;
  prodData: ParseTable.ProdDataRef;
  
  tm: TypeCons.TM;

 -- initialization/termination

  AssignDescriptors: PUBLIC PROC[
      qd: P1.ActionStack, vd: P1.ValueStack, ld: P1.LinkStack,
      pp: ParseTable.ProdDataRef,
      model: SMOps.MS] ~ {
    q ← qd; v ← vd; l ← ld; prodData ← pp;
    tm ← model.tm};


 -- error recovery (only)

  TokenValue: PUBLIC PROC[s: ParseTable.TSymbol] RETURNS [P1.TValue] ~ {
    RETURN [P1.nullTValue]};


 -- interpretation routines
 
  AtomList: TYPE ~ LIST OF ATOM;
  
  AtomV: PROC[i: CARDINAL] RETURNS[ATOM] ~ {
    RETURN [Atom.MakeAtom[P1.Substr[l[i], v[i].t]]]};
    
  ConsAtom: PROC[i: CARDINAL, rest: AtomList] RETURNS[AtomList] ~ {
    RETURN [CONS[AtomV[i], rest]]};
    
  InstName: PROC[type: ATOM] RETURNS[ATOM] ~ {
    RETURN [Atom.MakeAtom[(Atom.GetPName[type]).Cat["Impl"]]]};
    

  ProcessQueue: PUBLIC PROC[qI, top: CARDINAL] ~ {
    FOR i: CARDINAL IN [0..qI) DO

      GetRule: PROC[n: CARDINAL] RETURNS[CARDINAL] ~ TRUSTED INLINE {
        RETURN [prodData[n].rule]};

      top ← top-q[i].tag.pLength+1;
      SELECT GetRule[q[i].transition] FROM

       -- basic tree building
        0  => -- TABLE: CtoSParseData  TYPE: ParseTable  EXPORTS: SELF
	      -- GOAL:  goal

	      --TERMINALS:
	      --  id  num  lnum  flnum  string  lstring  char  atom
	      --  bracketed
	      --  ,  ;  :  =>  ←
	      --  =  #  <  >  <=  >=  ~
	      --  +  -  *  /  ↑  .  @
	      --  RECORD  POINTER  REF  VAR
	      --  LIST  ARRAY  DESCRIPTOR
	      --  PROCEDURE  PROC  PORT  SIGNAL  ERROR  PROCESS
	      --  PROGRAM  MONITOR  DEFINITIONS  ZONE  RELATIVE  LONG
	      --  TYPE  FRAME  TO  ORDERED  UNCOUNTED
	      --  BASE  OF  PACKED  RETURNS  SAFE  UNSAFE
	      --  MONITORED  MACHINE  DEPENDENT
	      --  DIRECTORY  IMPORTS  EXPORTS  SHARES  LOCKS  USING
	      --  PUBLIC  PRIVATE  CEDAR  CHECKED  TRUSTED  UNCHECKED
	      --  READONLY  CODE
	      --  ABS  ALL  AND  APPLY  CONS  MAX  MIN  MOD
	      --  NOT  OR  ORD  PRED  LENGTH  NEW  START  SUCC  VAL
	      --  FORK  JOIN  LOOPHOLE  NARROW  ISTYPE   SIZE
	      --  FIRST  LAST  NIL  TRASH  NULL  IF  THEN  ELSE
	      --  WITH  FROM  FOR  IN
	      --  ANY
	      --  }  ENDCASE
	      --  {  BEGIN  SELECT

	      --ALIASES:
	      --  id       tokenID
	      --  num      tokenNUM
	      --  lnum     tokenLNUM
	      --  flnum    tokenFLNUM
	      --  string   tokenSTR
	      --  lstring  tokenLSTR
	      --  char     tokenCHAR
	      --  atom     tokenATOM
	      --  bracketed   tokenBRACKET
	      --  -        tokenMINUS
	      --  .        tokenDOT
	      --  =        tokenEQUAL
	      --  =>       tokenARROW
	      --  <        tokenLESS
	      --  <=       tokenLE
	      --  >        tokenGREATER
	      --  >=       tokenGE
	      --  #        tokenNE
	      --  ~        tokenTILDE
	      --  .        initialSymbol

	      --PRODUCTIONS:

              -- goal           ::= . module 
	  NULL;
        1  => -- module         ::= directory identlist cedar proghead trusted checked begin
	  {
	  d: Tree.Link ~ SMTypeCons.Domain[tm, v[top+3].n];
	  r: Tree.Link ~ SMTypeCons.Range[tm, v[top+3].n];
	  m: LIST OF Tree.Link ← NIL;
	  FOR ids: AtomList ← NARROW[v[top+1].n], ids.rest UNTIL ids = NIL DO
	    name: ATOM ~ ids.first;
	    m ← CONS[
	      TypeCons.MkDeclElem[tm, name, TypeCons.MkInterfaceType[tm, name]],
	      m];
	    ENDLOOP; 
	  TypeCons.PushLink[tm, TypeCons.MkArrow[
	    tm,
	    v[top].n,
	    TypeCons.MkArrow[tm, d,
	      TypeCons.MkCross2[tm, TypeCons.MkDeclReverse[tm, m], r]]]];
	  v[top].n ← v[top+1].n ← v[top+3].n ← NIL;
	  };
        2  => -- module         ::= directory identlist cedar defhead begin 
	  {
	  nIds: NAT ← 0;
	  range: LIST OF Tree.Link ← NIL;
	  FOR ids: AtomList ← NARROW[v[top+1].n], ids.rest UNTIL ids = NIL DO
	    range ← CONS[TypeCons.MkInterfaceType[tm, ids.first], range];  nIds ← nIds+1;
	    ENDLOOP; 
	  TypeCons.PushLink[tm, 
	    TypeCons.MkArrow[tm,
	      v[top].n,
	      TypeCons.MkArrow[tm,
	        v[top+3].n, 
	        IF nIds = 1 THEN range.first ELSE TypeCons.MkCrossReverse[tm, range]]
	      ]];
	  v[top].n ← v[top+1].n ← v[top+3].n ← NIL;
	  };
        3  => -- begin          ::= {
	      -- begin          ::= BEGIN
	  NULL;
        4  => -- includeitem    ::= id : FROM string using
	      -- includeitem    ::= id : TYPE using
	      -- includeitem    ::= id using
	  {
	  name: ATOM ~ AtomV[top];
	  v[top].n ← TypeCons.MkDeclElem[tm, name, TypeCons.MkInterfaceType[tm, name]];
	  };
        5  => -- includeitem    ::= id : TYPE id using
	  v[top].n ← TypeCons.MkDeclElem[
	  	tm, AtomV[top], TypeCons.MkInterfaceType[tm, AtomV[top+3]]];
        6  => -- cedar          ::= CEDAR
	      -- cedar          ::=
	  NULL;
        7  => -- proghead       ::= resident safe class arguments locks interface tilde public 
	  {v[top].n ← v[top+5].n; v[top+5].n ← NIL};
        8  => -- resident       ::= 
	  NULL;
        9  => -- defhead        ::= definitions locks imports shares tilde public 
	  {v[top].n ← v[top+2].n; v[top+2].n ← NIL};
       10  => -- definitions    ::= DEFINITIONS 
              -- locks          ::= LOCKS primary lambda
              -- lambda         ::= USING ident typeexp
	  NULL;
       11  => -- importitem     ::= id 
	  {
	  name: ATOM ~ AtomV[top];
	  v[top].n ← TypeCons.MkDeclElem[tm, InstName[name], name];
	  };
       12  => -- importitem     ::= id : id 
	  v[top].n ← TypeCons.MkDeclElem[tm, AtomV[top], AtomV[top+2]];
       13  => -- public         ::= PUBLIC
              -- public         ::= PRIVATE
              -- public         ::=
              -- idlist'        ::= id 
	  NULL;
       14  => -- exportitem     ::= id 
	  v[top].n ← AtomV[top];
       15  => -- identlist'     ::= id : 
              -- identlist'     ::= id position : 
	  v[top].n ← ConsAtom[top, NIL];
       16  => -- idlist'        ::= id , idlist' 
	  NULL;
       17  => -- identlist'     ::= id , identlist' 
	  {v[top].n ← ConsAtom[top, NARROW[v[top+2].n]]; v[top+2].n ← NIL};
       18  => -- identlist'     ::= id position , identlist' 
	  {v[top].n ← ConsAtom[top, NARROW[v[top+3].n]]; v[top+3].n ← NIL};
       19  => -- position       ::= bracketed 
	      -- interval       ::= bracketed 
              -- typeexp        ::= id 
	      -- range          ::= id
              -- typeid'        ::= id . id 
              -- typeid'        ::= typeid' . id 
              -- typeappl       ::= typeappl . id 
              -- typeid         ::= id id 
              -- typeid         ::= id typeid 
	      -- typeappl       ::= id bracketed 
              -- typeappl       ::= typeid bracketed 
              -- typeappl       ::= typeappl bracketed 
	      -- typecons       ::= interval 
              -- range          ::= id interval
              -- range          ::= typeid interval
	      -- typecons       ::= dependent { elementlist }
              -- ident     	::= id position :
              -- element        ::= id bracketed 
              -- element        ::= bracketed
	      -- typecons       ::= dependent monitored RECORD reclist
	      -- typecons       ::= ordered base pointertype
	      -- typecons       ::= VAR typeexp
	      -- typecons       ::= REF readonly typeexp
	      -- typecons       ::= REF readonly ANY
	      -- typecons       ::= REF
	      -- typecons       ::= LIST OF readonly typeexp
	      -- typecons       ::= packed ARRAY indextype OF typeexp
	      -- typecons       ::= DESCRIPTOR FOR readonly typeexp
	      -- typecons       ::= safe transfermode arguments
	      -- safe           ::=
	      -- arglist        ::= ANY
              -- returnlist     ::= RETURNS ANY
	      -- typecons       ::= id RELATIVE typeexp
              -- typecons       ::= typeid RELATIVE typeexp
	      -- typecons       ::= heap ZONE
	      -- typecons       ::= LONG typeexp
	      -- typecons       ::= FRAME bracketed
              -- monitored      ::= MONITORED
	      -- dependent      ::= MACHINE DEPENDENT
	      -- dependent      ::=
	      -- reclist        ::= bracketed
              -- reclist        ::= NULL
              -- pointertype    ::= pointerprefix
	      -- pointertype    ::= pointerprefix TO readonly typeexp
	      -- transfermode   ::= PROCEDURE
              -- transfermode   ::= PROC
	      -- transfermode   ::= PORT
	      -- transfermode   ::= SIGNAL
	      -- transfermode   ::= ERROR
	      -- transfermode   ::= PROCESS
	      -- transfermode   ::= PROGRAM
	      -- trusted        ::=
              -- binditem       ::= exp
              -- binditem       ::= id : exp
              -- binditem       ::= id ~ ~ exp
              -- caseexpitem    ::= caselabel => exp
	      -- casetest       ::= optrelation 
	      -- casetest       ::= exp 
	      -- caselabel      ::= ident typeexp
              -- optexp         ::= TRASH
              -- optexp         ::= NULL
              -- exp            ::= transferop lhs 
              -- exp            ::= IF exp THEN exp ELSE exp 
              -- exp            ::= casehead caseexplist ENDCASE => exp 
              -- exp            ::= lhs ← exp 
              -- exp            ::= bracketed ← exp 
              -- exp            ::= ERROR 
              -- disjunct       ::= disjunct OR conjunct 
              -- conjunct       ::= conjunct AND negation 
              -- negation       ::= ~ relation 
              -- negation       ::= NOT relation 
              -- relation       ::= sum optrelation 
              -- sum            ::= sum addop product 
              -- product        ::= product multop factor 
              -- optrelation    ::= NOT relationtail 
              -- relationtail   ::= IN range 
              -- relop          ::= = 
              -- relop          ::= # 
              -- relop          ::= < 
              -- relop          ::= <= 
              -- relop          ::= > 
              -- relop          ::= >= 
              -- addop          ::= + 
              -- addop          ::= - 
              -- multop         ::= * 
              -- multop         ::= / 
              -- multop         ::= MOD 
              -- factor         ::= addop primary 
              -- primary        ::= num 
              -- primary        ::= lnum 
              -- primary        ::= flnum 
              -- primary        ::= string 
              -- primary        ::= lstring 
              -- primary        ::= atom 
              -- primary        ::= NIL 
              -- primary        ::= prefixop bracketed
              -- primary        ::= VAL bracketed
              -- primary        ::= ALL bracketed
              -- primary        ::= new bracketed
              -- primary        ::= cons bracketed
              -- primary        ::= listcons bracketed
              -- primary        ::= typeop bracketed
              -- qualifier      ::= . prefixop 
              -- qualifier      ::= . typeop
              -- primary        ::= SIZE bracketed
              -- qualifier      ::= . SIZE
              -- primary        ::= ISTYPE bracketed 
              -- primary        ::= @ lhs
              -- primary        ::= DESCRIPTOR bracketed
	  NULL;
       20  => -- lhs            ::= id 
              -- element        ::= id
	      -- ident          ::= id : 
              -- lhs            ::= char 
              -- lhs            ::= NARROW bracketed
              -- lhs            ::= LOOPHOLE bracketed
              -- lhs            ::= APPLY bracketed
              -- qualifier      ::= bracketed
              -- qualifier      ::= . id
              -- qualifier      ::= ↑
              -- transferop     ::= SIGNAL
              -- transferop     ::= ERROR
              -- transferop     ::= START
              -- transferop     ::= JOIN
              -- transferop     ::= NEW 
              -- transferop     ::= FORK
              -- prefixop       ::= LONG 
              -- prefixop       ::= ABS 
              -- prefixop       ::= PRED 
              -- prefixop       ::= SUCC 
              -- prefixop       ::= ORD 
              -- prefixop       ::= MIN 
              -- prefixop       ::= MAX 
              -- prefixop       ::= BASE
              -- prefixop       ::= LENGTH
              -- typeop         ::= CODE
              -- typeop         ::= FIRST
              -- typeop         ::= LAST
              -- typeop         ::= NIL
	  NULL;
       21  => -- directory      ::= DIRECTORY ;
	  v[top].n ← TypeCons.MkDeclReverse[tm, CONS[OptionDecl[tm], NIL]];
       22  => -- imports        ::= IMPORTS
	  v[top].n ← TypeCons.MkDeclReverse[tm, NIL];
       23  => -- exports        ::= EXPORTS 
	  v[top].n ← TypeCons.MkCrossReverse[tm, NIL];
       24  => -- new            ::= NEW
              -- cons           ::= CONS
              -- listcons       ::= LIST
              -- pointerprefix  ::= POINTER
              -- using          ::= USING bracketed
              -- elementlist    ::=
	      -- caseexplist    ::=
	  NULL;
       25  => -- includelist    ::= includeitem
	      -- importlist     ::= importitem
	      -- exportlist     ::= exportitem
	  v[top].n ← CONS[v[top].n, NIL];
       26  => -- elementlist'   ::= element
	      -- bindlist       ::= binditem
	      -- caselabel'     ::= casetest 
	      -- caseexplist'   ::= caseexpitem
	  NULL;
       27  => -- includelist    ::= includelist , includeitem
	      -- importlist     ::= importlist , importitem
	      -- exportlist     ::= exportlist , exportitem
	  {v[top].n ← CONS[v[top+2].n, NARROW[v[top].n]];  v[top+2].n ← NIL};
       28  => -- elementlist'   ::= elementlist' , element
	      -- bindlist       ::= bindlist , binditem
	      -- caselabel'     ::= caselabel' , casetest 
	      -- caseexplist'   ::= caseexplist' , caseexpitem
              -- idlist         ::= idlist'
	      -- identlist      ::= identlist'
	      -- caselabel      ::= caselabel' 
	  NULL;
       29  => -- directory      ::= DIRECTORY includelist ;
	  {
	  decls: LIST OF Tree.Link ~ CONS[OptionDecl[tm], NARROW[v[top+1].n]];
	  v[top].n ← TypeCons.MkDeclReverse[tm, decls];
	  v[top+1].n ← NIL;
	  };
       30  => -- imports        ::= IMPORTS importlist
	  {v[top].n ← TypeCons.MkDeclReverse[tm, NARROW[v[top+1].n]]; v[top+1].n ← NIL};
       31  => -- exports        ::= EXPORTS exportlist
       	  {v[top].n ← TypeCons.MkCrossReverse[tm, NARROW[v[top+1].n]]; v[top+1].n ← NIL};
       32  => -- class          ::= PROGRAM 
              -- safe           ::= UNSAFE
	      -- casehead       ::= SELECT exp FROM
	      -- class          ::= MONITOR 
              -- packed		::= PACKED
	      -- safe           ::= SAFE
	      -- readonly       ::= READONLY
	      -- ordered        ::= ORDERED
	      -- base           ::= BASE
	      -- heap           ::= UNCOUNTED
	      -- casehead       ::= WITH binditem SELECT optexp FROM
	      -- packed		::=
	      -- readonly       ::=
	      -- monitored      ::=
	      -- ordered        ::=
	      -- base           ::=
	      -- heap           ::=
	  NULL;
       33  => -- interface      ::= imports exports shares
	  {v[top].n ← TypeCons.MkArrow[tm, v[top].n, v[top+1].n]; v[top+1].n ← NIL};
       34  => -- shares         ::= SHARES idlist 
	      -- tilde          ::= ~ 
	      -- tilde          ::= = 
	      -- typeid         ::= typeid'
	      -- typeexp        ::= typeid 
	      -- typeexp        ::= typecons 
	      -- typecons       ::= typeappl 
	      -- elementlist    ::= elementlist' 
	      -- pointerprefix  ::= POINTER interval 
	      -- indextype      ::= typeexp 
	      -- arguments      ::= arglist returnlist 
	      -- arglist        ::= bracketed 
	      -- returnlist     ::= RETURNS bracketed 
	      -- caseexplist    ::= caseexplist' 
	      -- caseexplist    ::= caseexplist' , 
	      -- optexp         ::= exp 
	      -- exp            ::= disjunct 
	      -- disjunct       ::=C conjunct 
	      -- conjunct       ::=C negation 
	      -- negation       ::=C relation 
	      -- relation       ::= sum 
	      -- optrelation    ::= relationtail 
	      -- relationtail   ::= relop sum 
	      -- range          ::= interval 
	      -- range          ::= typeid 
	      -- sum            ::=C product 
	      -- product        ::=C factor 
	      -- factor         ::=C primary 
	      -- primary        ::= lhs 
	      -- lhs            ::= bracketed 
	      -- lhs            ::= lhs qualifier 
              -- new            ::= lhs . NEW
              -- cons           ::= lhs . CONS
              -- listcons       ::= lhs . LIST
	  NULL;
       35  => -- directory      ::= 
	  v[top].n ← TypeCons.MkDeclReverse[tm, CONS[OptionDecl[tm], NIL]];
       36  => -- using          ::= 
	      -- locks          ::= 
	      -- lambda         ::= 
	  NULL;
       37  => -- imports        ::= 
	  v[top].n ← TypeCons.MkDeclReverse[tm, NIL];
       38  => -- exports        ::= 
	  v[top].n ← TypeCons.MkCrossReverse[tm, NIL];
       39  => -- shares         ::= 
	      -- arglist        ::= 
	      -- returnlist     ::= 
	      -- indextype      ::=
	      -- optexp         ::=
	      -- checked         ::=
	      -- checked         ::= CHECKED
	      -- checked         ::= TRUSTED
	      -- checked         ::= UNCHECKED
	  NULL;

       -- error or unimplemented
	ENDCASE =>  ERROR;

      ENDLOOP};

  OptionDecl: PROC[tm: TypeCons.TM] RETURNS[Tree.Link] ~ {
    name: ATOM ~ Atom.MakeAtom["&options"];
    RETURN [TypeCons.MkDeclElem[tm, name, TypeCons.MkStringType[tm]]]};
     
  }.