-- file Pass1T.mesa rewritten by PGS, 12-May-83 14:22 -- file Pass1T.mesa rewritten by PGS, 2-May-83 9:07 -- last modified by Satterthwaite, May 2, 1983 9:06 am -- last modified by Donahue, 9-Dec-81 10:48:31 DIRECTORY ComData: TYPE USING [idANY, idINT, idLOCK], ParseTable: TYPE USING [ActionEntry, ProdDataRef, TSymbol], P1: TYPE USING [ ActionStack, LinkStack, Value, ValueStack, nullValue, InputLoc, IdOfFirst, IdOfLock, IdOfRest], Symbols: TYPE USING [Name, nullName], Tree: TYPE USING [AttrId, Link, Map, NodeName, Null], TreeOps: TYPE USING [ FreeTree, ListLength, MakeNode, ExtractTree, InsertTree, OpName, PopTree, PushTree, PushHash, PushList, PushLit, PushProperList, PushSe, PushNode, SetAttr, SetInfo, UpdateList]; Pass1T: PROGRAM IMPORTS P1, TreeOps, dataPtr: ComData EXPORTS P1 = { -- parse tree building OPEN TreeOps; Op: TYPE = Tree.NodeName; -- local data base (supplied by parser) v: P1.ValueStack; l: P1.LinkStack; q: P1.ActionStack; prodData: ParseTable.ProdDataRef; -- initialization/termination AssignDescriptors: PUBLIC PROC [ qd: P1.ActionStack, vd: P1.ValueStack, ld: P1.LinkStack, pp: ParseTable.ProdDataRef] = { q ← qd; v ← vd; l ← ld; prodData ← pp}; -- error recovery (only) TokenValue: PUBLIC PROC [s: ParseTable.TSymbol] RETURNS [P1.Value] = { RETURN [P1.nullValue]}; -- stack manipulation -- note that r and s may be overlaid in some parameterizations PushHashV: PROC [k: NAT] = {PushHash[v[k].r]}; PushLitV: PROC [k: NAT] = {PushLit[v[k].r]}; PushNodeV: PROC [k: NAT, count: INTEGER] = {PushNode[v[k].s, count]}; PushListV: PROC [k: NAT] = {PushList[v[k].s]}; PushProperListV: PROC [k: NAT] = {PushProperList[v[k].s]}; SetAttrV: PROC [attr: Tree.AttrId, k: NAT] = {SetAttr[attr, v[k].s]}; SetAttrs: PROC [attr1, attr2, attr3: BOOL ← FALSE] = { SetAttr[1,attr1]; SetAttr[2,attr2]; SetAttr[3,attr3]}; -- value manipulation BoolV: PROC [k: NAT] RETURNS [BOOL] = {RETURN [v[k].s]}; SetBoolV: PROC [k: NAT, b: BOOL] = {v[k].s ← b}; OpV: PROC [k: NAT] RETURNS [Op] = {RETURN [v[k].s]}; SetOpV: PROC [k: NAT, op: Op] = {v[k].s ← op}; NegatedV: PROC [k: NAT] RETURNS [Op] = { op: Op = v[k].s; RETURN [SELECT op FROM relE => relN, relN => relE, relL => relGE, relGE => relL, relG => relLE, relLE => relG, in => notin, notin => in, ENDCASE => op]}; -- shared processing routines DetachItem: Tree.Map = {PushTree[t]; RETURN [Tree.Null]}; AnonField: PROC [type, default: Tree.Link, top: CARDINAL] = { PushField[Symbols.nullName, type, default, top]}; PushField: PROC [id: Symbols.Name, type, default: Tree.Link, top: CARDINAL] = { PushHash[id]; PushTree[type]; PushTree[default]; PushNode[decl,3]; LinkToSource[top]; SetAttrs[FALSE,public,FALSE]}; -- the interpretation rules LinkToSource: PROC [index: CARDINAL] = {SetInfo[l[index]]}; -- propagated attributes public: BOOL; machineDep: BOOL; trusted, checked: BOOL; safety: BOOL; ProcessQueue: PUBLIC PROC [qI, top: CARDINAL] = { t1, t2: Tree.Link; FOR i: CARDINAL IN [0..qI) DO top ← top-q[i].tag.pLength+1; SELECT prodData[q[i].transition].rule FROM -- basic tree building 0 => -- TABLE: MesaTab TYPE: ParseTable EXPORTS: CBinary -- GOAL: goal --TERMINALS: -- id num lnum flnum string lstring char atom -- , ; : .. => ← -- = # < > <= >= ~ -- + - * / ↑ . @ ! '| -- RECORD POINTER REF VAR -- LIST ARRAY SEQUENCE DESCRIPTOR -- PROCEDURE PROC PORT SIGNAL ERROR PROCESS -- PROGRAM MONITOR DEFINITIONS ZONE RELATIVE LONG -- TYPE FRAME TO ORDERED UNCOUNTED PAINTED -- BASE OF PACKED RETURNS SAFE UNSAFE -- MONITORED OVERLAID COMPUTED MACHINE DEPENDENT -- DIRECTORY IMPORTS EXPORTS SHARES LOCKS USING -- PUBLIC PRIVATE CEDAR CHECKED TRUSTED UNCHECKED -- ENTRY INTERNAL INLINE 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 DECREASING IN -- THROUGH UNTIL WHILE REPEAT FINISHED -- RETURN EXIT LOOP GOTO GO -- FREE WAIT RESTART NOTIFY BROADCAST STOP -- RESUME REJECT CONTINUE RETRY TRANSFER STATE -- OPEN ENABLE ANY EXITS -- ) ] } END ENDLOOP ENDCASE -- ( [ { BEGIN DO SELECT --ALIASES: -- id tokenID -- num tokenNUM -- lnum tokenLNUM -- flnum tokenFLNUM -- string tokenSTR -- lstring tokenLSTR -- char tokenCHAR -- atom tokenATOM -- - tokenMINUS -- . tokenDOT -- .. tokenDOTS -- = tokenEQUAL -- => tokenARROW -- < tokenLESS -- <= tokenLE -- > tokenGREATER -- >= tokenGE -- # tokenNE -- ~ tokenTILDE -- . initialSymbol --PRODUCTIONS: -- goal ::= . module . -- goal ::= . module .. NULL; 1 => -- module ::= directory identlist cedar proghead trusted checked block BEGIN IF ~BoolV[top+6] THEN InsertTree[Tree.Null,2]; PushTree[Tree.Null]; t1 ← MakeNode[body,4]; t2 ← ExtractTree[2]; PushTree[ExtractTree[5]]; PushTree[t2]; PushTree[t1]; SetAttr[1,checked]; SetAttr[2,trusted]; trusted ← BoolV[top+4]; checked ← BoolV[top+5]; PushNode[decl,3]; LinkToSource[top+1]; SetAttrs[TRUE,TRUE,FALSE]; PushNode[module,6]; LinkToSource[top]; SetAttrV[1,top+3]; END; 2 => -- module ::= directory identlist cedar defhead defbody BEGIN IF ~BoolV[top+4] THEN InsertTree[Tree.Null,2]; PushTree[Tree.Null]; t1 ← MakeNode[body,4]; t2 ← ExtractTree[2]; PushTree[ExtractTree[5]]; PushTree[t2]; PushTree[t1]; PushNode[decl,3]; LinkToSource[top+1]; SetAttrs[TRUE,TRUE,FALSE]; PushNode[module,6]; LinkToSource[top]; SetAttrV[1,top+3]; END; 3 => -- includeitem ::= id : FROM string using BEGIN PushLitV[top+3]; PushHashV[top]; PushNode[diritem,-3]; LinkToSource[top]; END; 4 => -- includeitem ::= id : TYPE using -- includeitem ::= id using BEGIN PushTree[Tree.Null]; PushHashV[top]; PushNode[diritem,-3]; LinkToSource[top]; END; 5 => -- includeitem ::= id : TYPE id using BEGIN PushHashV[top+3]; PushHashV[top]; PushNode[diritem,-3]; LinkToSource[top]; END; 6 => -- cedar ::= CEDAR safety ← trusted ← checked ← TRUE; 7 => -- cedar ::= safety ← trusted ← checked ← FALSE; 8 => -- proghead ::= resident safe class arguments locks interface tilde public BEGIN t1 ← ExtractTree[4]; PushTree[ExtractTree[5]]; PushTree[ExtractTree[5]]; PushNode[programTC,2]; SetAttrV[1,top+2]; SetAttrV[3,top+1]; IF ~BoolV[top+2] OR t1 # Tree.Null THEN PushTree[t1] ELSE { PushHash[P1.IdOfLock[]]; PushTree[Tree.Null]; PushNode[lambda,-2]; SetAttr[1,TRUE]; SetAttr[2,public]}; machineDep ← FALSE; END; 9 => -- resident ::= {public ← FALSE; SetBoolV[top,FALSE]; l[top] ← P1.InputLoc[]}; 10 => -- defhead ::= definitions locks imports shares tilde public BEGIN t1 ← ExtractTree[3]; t2 ← PopTree[]; PushTree[Tree.Null]; PushTree[t2]; PushNode[definitionTC,0]; PushTree[t1]; SetBoolV[top,FALSE]; machineDep ← FALSE; END; 11 => -- definitions ::= DEFINITIONS public ← TRUE; 12 => -- defbody ::= BEGIN open declist END -- defbody ::= BEGIN open declist ; END -- defbody ::= { open declist } -- defbody ::= { open declist ; } {PushListV[top+2]; PushTree[Tree.Null]; SetBoolV[top,TRUE]}; 13 => -- locks ::= LOCKS primary lambda {PushNode[lambda,-2]; SetAttr[1,FALSE]; SetAttr[2,FALSE]}; 14 => -- lambda ::= USING ident typeexp BEGIN PushTree[Tree.Null]; PushNode[decl,3]; LinkToSource[top+1]; SetAttrs[FALSE,FALSE,FALSE]; END; 15 => -- moduleitem ::= id BEGIN PushHashV[top]; PushHashV[top]; PushNode[item,2]; SetAttr[1,FALSE]; LinkToSource[top]; END; 16 => -- moduleitem ::= id : id BEGIN PushHashV[top]; PushHashV[top+2]; PushNode[item,2]; SetAttr[1,TRUE]; LinkToSource[top]; END; 17 => -- declaration ::= identlist public entry readonly typeexp initialization BEGIN IF BoolV[top+3] THEN { t1 ← PopTree[]; PushNode[varTC,1]; SetAttrs[FALSE,FALSE,TRUE]; PushTree[t1]}; IF OpV[top+2] # none THEN PushNodeV[top+2,1]; PushNode[decl,3]; LinkToSource[top]; SetAttrV[1,top+5]; SetAttr[2,public]; public ← BoolV[top+1]; END; 18 => -- declaration ::= identlist public TYPE tilde public typeexp default BEGIN public ← BoolV[top+4]; PushNode[typedecl,3]; LinkToSource[top]; SetAttrs[TRUE,public,FALSE]; public ← BoolV[top+1]; END; 19 => -- declaration ::= identlist public TYPE optsize BEGIN PushNode[opaqueTC,1]; PushTree[Tree.Null]; PushNode[typedecl,3]; LinkToSource[top]; SetAttrs[TRUE,public,FALSE]; public ← BoolV[top+1]; END; 20 => -- public ::= PUBLIC {SetBoolV[top,public]; public ← TRUE}; 21 => -- public ::= PRIVATE -- procaccess ::= {SetBoolV[top, public]; public ← FALSE}; 22 => -- public ::= SetBoolV[top,public]; 23 => -- entry ::= ENTRY SetOpV[top,entry]; 24 => -- entry ::= INTERNAL SetOpV[top,internal]; 25 => -- entry ::= {SetOpV[top,none]; l[top] ← P1.InputLoc[]}; 26 => -- idlist' ::= id -- identlist' ::= id : {PushHashV[top]; v[top].s ← -1}; 27 => -- identlist' ::= id position : {PushHashV[top]; PushNode[item,-2]; v[top].s ← -1}; 28 => -- idlist' ::= id , idlist' -- identlist' ::= id , identlist' {PushHashV[top]; v[top].s ← v[top+2].s-1}; 29 => -- identlist' ::= id position , identlist' BEGIN PushTree[ExtractTree[-(v[top+3].s-1)]]; PushHashV[top]; PushNode[item,-2]; v[top].s ← v[top+3].s-1; END; 30 => -- position ::= ( exp optbits ) PushNode[item,2]; 31 => -- optbits ::= : bounds -- interval ::= [ bounds ] PushNode[intCC,2]; 32 => -- interval ::= [ bounds ) PushNode[intCO,2]; 33 => -- interval ::= ( bounds ] PushNode[intOC,2]; 34 => -- interval ::= ( bounds ) PushNode[intOO,2]; 35 => -- typeexp ::= id -- range ::= id PushHashV[top]; 36 => -- typeid' ::= id . id {PushHashV[top]; PushHashV[top+2]; PushNode[dot,2]}; 37 => -- typeid' ::= typeid' . id -- typeappl ::= typeappl . id {PushHashV[top+2]; PushNode[dot,2]}; 38 => -- typeid ::= id id {PushHashV[top+1]; PushHashV[top]; PushNode[dot,2]}; 39 => -- typeid ::= id typeid {PushHashV[top]; PushNode[dot,2]}; 40 => -- typeappl ::= id length {PushHashV[top]; PushNode[apply,-2]}; 41 => -- typeappl ::= typeid length -- typeappl ::= typeappl length PushNode[apply,2]; 42 => -- typecons ::= interval {PushSe[dataPtr.idINT]; PushNode[subrangeTC,-2]}; 43 => -- typecons ::= id interval -- range ::= id interval {PushHashV[top]; PushNode[subrangeTC,-2]}; 44 => -- typecons ::= typeid interval -- range ::= typeid interval PushNode[subrangeTC,2]; 45 => -- typecons ::= dependent { elementlist } BEGIN PushListV[top+2]; PushNode[enumeratedTC,1]; SetAttr[1,public]; SetAttr[2,machineDep]; machineDep ← BoolV[top]; END; 46 => -- ident ::= id position : -- element ::= id ( exp ) {PushHashV[top]; PushNode[item,-2]}; 47 => -- element ::= ( exp ) {PushHash[Symbols.nullName]; PushNode[item,-2]}; 48 => -- typecons ::= dependent monitored RECORD reclist BEGIN IF ~BoolV[top+1] THEN PushNode[recordTC,1] ELSE { t1 ← PopTree[]; v[top+2].s ← ListLength[t1]; t1 ← UpdateList[t1,DetachItem]; t1 ← FreeTree[t1]; PushList[v[top+2].s+1]; PushNode[monitoredTC,1]}; SetAttr[1,machineDep]; SetAttrV[2,top+3]; machineDep ← BoolV[top]; SetAttr[3,TRUE]; END; 49 => -- typecons ::= ordered base pointertype BEGIN t2 ← MakeNode[pointerTC,1]; t1 ← PopTree[]; PushTree[t2]; SetAttrV[1,top]; SetAttrV[2,top+1]; SetAttrV[3,top+2]; IF t1 # Tree.Null THEN {PushTree[t1]; PushNode[subrangeTC,2]}; END; 50 => -- typecons ::= VAR typeexp {PushNode[varTC,1]; SetAttrs[FALSE,FALSE,FALSE]}; 51 => -- typecons ::= REF readonly typeexp BEGIN PushNode[refTC,1]; SetAttr[1,FALSE]; SetAttr[2,FALSE]; SetAttrV[3,top+1]; PushNode[longTC,1]; END; 52 => -- typecons ::= REF readonly ANY BEGIN PushNode[anyTC, 0]; PushNode[refTC,1]; SetAttr[1,FALSE]; SetAttr[2,FALSE]; SetAttrV[3,top+1]; PushNode[longTC,1]; END; 53 => -- typecons ::= REF BEGIN PushNode[anyTC, 0]; PushNode[refTC,1]; SetAttrs[FALSE,FALSE,FALSE]; PushNode[longTC,1]; END; 54 => -- typecons ::= LIST OF readonly typeexp BEGIN PushField[P1.IdOfFirst[], PopTree[], Tree.Null, top]; PushField[P1.IdOfRest[], MakeNode[linkTC,0], Tree.Null, top]; PushList[2]; PushNode[recordTC,1]; SetAttrs[FALSE,FALSE,FALSE]; PushNode[listTC,1]; SetAttr[1,FALSE]; SetAttr[2,FALSE]; SetAttrV[3,top+2]; PushNode[longTC,1]; END; 55 => -- typecons ::= packed ARRAY indextype OF typeexp {PushNode[arrayTC,2]; SetAttrV[3,top]}; 56 => -- typecons ::= DESCRIPTOR FOR readonly typeexp {PushNode[arraydescTC,1]; SetAttrV[3,top+2]}; 57 => -- typecons ::= safe transfermode arguments {PushNodeV[top+1,2]; SetAttrV[3,top]}; 58 => -- safe ::= {SetBoolV[top,safety]; l[top] ← P1.InputLoc[]}; 59 => -- arglist ::= ANY -- returnlist ::= RETURNS ANY PushNode[anyTC, 0]; 60 => -- typecons ::= id RELATIVE typeexp {PushHashV[top]; PushNode[relativeTC,-2]}; 61 => -- typecons ::= typeid RELATIVE typeexp PushNode[relativeTC,2]; 62 => -- typecons ::= heap ZONE {PushNode[zoneTC,0]; SetAttrV[1,top]; SetAttr[2,FALSE]}; 63 => -- typecons ::= LONG typeexp PushNode[longTC,1]; 64 => -- typecons ::= FRAME [ id ] {PushHashV[top+2]; PushNode[frameTC,1]}; 65 => -- typecons ::= id PAINTED typeexp {PushHashV[top]; PushNode[paintTC,-2]}; 66 => -- typecons ::= typeid PAINTED typeexp PushNode[paintTC,2]; 67 => -- monitored ::= MONITORED BEGIN PushSe[dataPtr.idLOCK]; PushField[P1.IdOfLock[], PopTree[], Tree.Null, top]; SetBoolV[top,TRUE]; END; 68 => -- dependent ::= MACHINE DEPENDENT {SetBoolV[top,machineDep]; machineDep ← TRUE}; 69 => -- dependent ::= SetBoolV[top,machineDep]; 70 => -- reclist ::= [ ] -- reclist ::= NULL {PushList[0]; SetBoolV[top,FALSE]}; 71 => -- reclist ::= [ pairlist ] -- reclist ::= [ typelist ] {PushListV[top+1]; SetBoolV[top,FALSE]}; 72 => -- reclist ::= [ pairlist , variantpair ] {PushList[v[top+1].s+1]; SetBoolV[top,TRUE]}; 73 => -- reclist ::= [ variantpart default ] {t1 ← PopTree[]; AnonField[PopTree[], t1, top]; SetBoolV[top,TRUE]}; 74 => -- pairitem ::= identlist public typeexp default -- variantpair ::= identlist public variantpart default BEGIN PushNode[decl,3]; LinkToSource[top]; SetAttrs[FALSE,public,FALSE]; public ← BoolV[top+1]; END; 75 => -- variantpart ::= SELECT vcasehead FROM variantlist ENDCASE -- variantpart ::= SELECT vcasehead FROM variantlist , ENDCASE BEGIN PushListV[top+3]; PushNode[unionTC,2]; SetAttr[1,machineDep]; SetAttrV[2,top+1]; END; 76 => -- variantpart ::= packed SEQUENCE vcasehead OF typeexp BEGIN PushNode[sequenceTC,2]; SetAttr[1,machineDep]; SetAttrV[2,top+2]; SetAttrV[3,top]; END; 77 => -- vcasehead ::= ident public tagtype BEGIN PushTree[Tree.Null]; PushNode[decl,3]; LinkToSource[top]; SetAttrs[FALSE,public,FALSE]; public ← BoolV[top+1]; SetBoolV[top,FALSE]; END; 78 => -- vcasehead ::= COMPUTED tagtype {AnonField[PopTree[], Tree.Null, top]; SetBoolV[top,FALSE]}; 79 => -- vcasehead ::= OVERLAID tagtype {AnonField[PopTree[], Tree.Null, top]; SetBoolV[top,TRUE]}; 80 => -- tagtype ::= * PushNode[implicitTC,0]; 81 => -- variantitem ::= idlist => reclist BEGIN PushNode[variantTC,1]; SetAttr[1,machineDep]; SetAttrV[2,top+2]; SetAttr[3,TRUE]; PushTree[Tree.Null]; PushNode[typedecl,3]; LinkToSource[top]; SetAttrs[TRUE,public,FALSE]; END; 82 => -- typelist ::= typecons default -- typelist ::= typeid default {t1 ← PopTree[]; AnonField[PopTree[], t1, top]; v[top].s ← -1}; 83 => -- typelist ::= id {PushHashV[top]; AnonField[PopTree[], Tree.Null, top]; v[top].s ← -1}; 84 => -- typelist ::= id ← defaultopt {t1 ← PopTree[]; PushHashV[top]; AnonField[PopTree[], t1, top]; v[top].s ← -1}; 85 => -- typelist ::= typecons default , typelist -- typelist ::= typeid default , typelist BEGIN t1 ← ExtractTree[-(v[top+3].s-1)]; AnonField[ExtractTree[-(v[top+3].s-1)], t1, top]; v[top].s ← v[top+3].s-1; END; 86 => -- typelist ::= id , typelist {PushHashV[top]; AnonField[PopTree[], Tree.Null, top]; v[top].s ← v[top+2].s-1}; 87 => -- typelist ::= id ← defaultopt , typelist BEGIN t1 ← ExtractTree[-(v[top+4].s-1)]; PushHashV[top]; AnonField[PopTree[], t1, top]; v[top].s ← v[top+4].s-1; END; 88 => -- pointertype ::= pointerprefix {PushSe[dataPtr.idANY]; SetBoolV[top,FALSE]}; 89 => -- pointertype ::= pointerprefix TO readonly typeexp SetBoolV[top, BoolV[top+2]]; 90 => -- transfermode ::= PROCEDURE -- transfermode ::= PROC SetOpV[top,procTC]; 91 => -- transfermode ::= PORT SetOpV[top,portTC]; 92 => -- transfermode ::= SIGNAL SetOpV[top,signalTC]; 93 => -- transfermode ::= ERROR SetOpV[top,errorTC]; 94 => -- transfermode ::= PROCESS SetOpV[top,processTC]; 95 => -- transfermode ::= PROGRAM SetOpV[top,programTC]; 96 => -- initialization ::= {PushTree[Tree.Null]; SetBoolV[top,FALSE]}; 97 => -- initvalue ::= procaccess trusted checked inline block BEGIN IF ~BoolV[top+4] THEN InsertTree[Tree.Null,2]; PushTree[Tree.Null]; PushNode[body,4]; SetAttrV[3,top+3]; SetAttr[1,checked]; SetAttr[2,trusted]; trusted ← BoolV[top+1]; checked ← BoolV[top+2]; public ← BoolV[top]; END; 98 => -- initvalue ::= CODE PushNode[signalinit,0]; 99 => -- initvalue ::= procaccess trusted checked MACHINE CODE BEGIN codelist END -- initvalue ::= procaccess trusted checked MACHINE CODE { codelist } BEGIN PushProperListV[top+6]; PushNode[inline,1]; SetAttr[1,checked]; SetAttr[2,trusted]; trusted ← BoolV[top+1]; checked ← BoolV[top+2]; public ← BoolV[top]; END; 100 => -- trusted ::= SetBoolV[top,trusted]; 101 => -- codelist ::= orderlist {PushListV[top]; v[top].s ← 1}; 102 => -- codelist ::= codelist ; orderlist {PushListV[top+2]; v[top].s ← v[top].s+1}; 103 => -- statement ::= IF exp THEN statement {PushTree[Tree.Null]; PushNode[if,3]; LinkToSource[top]}; 104 => -- statement ::= IF exp THEN balstmt ELSE statement -- balstmt ::= IF exp THEN balstmt ELSE balstmt {PushNode[if,3]; LinkToSource[top]}; 105 => -- statement ::= casehead casestmtlist ENDCASE => statement -- balstmt ::= casehead casestmtlist ENDCASE => balstmt BEGIN t1 ← PopTree[]; PushProperListV[top+1]; PushTree[t1]; IF BoolV[top] THEN PushNode[bind,4] ELSE PushNode[case,3]; LinkToSource[top]; END; 106 => -- basicstmt ::= lhs BEGIN t1 ← PopTree[]; PushTree[t1]; IF OpName[t1] # apply THEN { PushTree[Tree.Null]; PushNode[apply,2]; SetAttr[1, FALSE]}; LinkToSource[top]; END; 107 => -- basicstmt ::= lhs ← exp {PushNode[assign,2]; LinkToSource[top]}; 108 => -- basicstmt ::= [ explist ] ← exp {PushNode[extract,2]; LinkToSource[top]}; 109 => -- basicstmt ::= trusted checked block BEGIN IF BoolV[top+2] THEN { PushNode[block,2]; SetAttr[1,checked]; SetAttr[2,trusted]; LinkToSource[top+2]} ELSE IF checked # BoolV[top+1] OR (~checked AND trusted) THEN { PushNode[checked,1]; SetAttr[1,checked]; SetAttr[2,trusted]; LinkToSource[top+2]}; trusted ← BoolV[top]; checked ← BoolV[top+1]; t1 ← ExtractTree[2]; IF t1 # Tree.Null THEN { PushTree[t1]; PushNode[open,-2]; LinkToSource[top+2]}; END; 110 => -- basicstmt ::= casehead casestmtlist ENDCASE BEGIN PushProperListV[top+1]; PushTree[Tree.Null]; IF BoolV[top] THEN PushNode[bind,4] ELSE PushNode[case,3]; LinkToSource[top]; END; 111 => -- basicstmt ::= forclause dotest DO scope doexit ENDLOOP BEGIN IF BoolV[top+3] THEN { t1 ← PopTree[]; t2 ← PopTree[]; PushNode[block,2]; SetAttr[1,checked]; SetAttr[2,trusted]; LinkToSource[top+2]; PushTree[t2]; PushTree[t1]}; PushNode[do,6]; LinkToSource[top]; END; 112 => -- basicstmt ::= EXIT {PushNode[exit,0]; LinkToSource[top]}; 113 => -- basicstmt ::= LOOP {PushNode[loop,0]; LinkToSource[top]}; 114 => -- basicstmt ::= GOTO id {PushHashV[top+1]; PushNode[goto,1]; LinkToSource[top]}; 115 => -- basicstmt ::= GO TO id {PushHashV[top+2]; PushNode[goto,1]; LinkToSource[top]}; 116 => -- basicstmt ::= RETURN optargs {PushNode[return,1]; SetAttrV[3,top+1]; LinkToSource[top]}; 117 => -- basicstmt ::= transfer lhs {PushNodeV[top,1]; LinkToSource[top]}; 118 => -- basicstmt ::= free [ exp optcatch ] BEGIN IF BoolV[top+3] THEN { t1 ← PopTree[]; PushTree[Tree.Null]; PushTree[t1]; PushNode[free,4]} ELSE {PushTree[Tree.Null]; PushNode[free,3]}; LinkToSource[top]; END; 119 => -- basicstmt ::= WAIT lhs {PushNode[wait,1]; LinkToSource[top]}; 120 => -- basicstmt ::= ERROR {PushNode[syserror,0]; LinkToSource[top]}; 121 => -- basicstmt ::= STOP {PushNode[stop,0]; LinkToSource[top]}; 122 => -- basicstmt ::= NULL {PushNode[null,0]; LinkToSource[top]}; 123 => -- basicstmt ::= RESUME optargs {PushNode[resume,1]; SetAttrV[3,top+1]; LinkToSource[top]}; 124 => -- basicstmt ::= REJECT {PushNode[reject,0]; LinkToSource[top]}; 125 => -- basicstmt ::= CONTINUE {PushNode[continue,0]; LinkToSource[top]}; 126 => -- basicstmt ::= RETRY {PushNode[retry,0]; LinkToSource[top]}; 127 => -- basicstmt ::= lhs ← STATE {PushNode[dst,1]; LinkToSource[top]}; 128 => -- basicstmt ::= STATE ← exp {PushNode[lst,1]; LinkToSource[top]}; 129 => -- block ::= BEGIN scope exits END -- block ::= { scope exits } IF BoolV[top+2] THEN { -- an exits clause is present; build a label node IF BoolV[top+1] THEN { t1 ← PopTree[]; PushNode[block,2]; SetAttr[1,checked]; SetAttr[2,trusted]; LinkToSource[top+1]; PushTree[t1]}; SetBoolV[top,FALSE]; PushNode[label,2]; LinkToSource[top]} ELSE -- things are unchanged; propogate the "block needs to be made" bit SetBoolV[top,BoolV[top+1]]; 130 => -- scope ::= open enables statementlist BEGIN PushListV[top+2]; SetBoolV[top,FALSE]; IF BoolV[top+1] THEN {PushNode[enable,2]; LinkToSource[top+1]}; END; 131 => -- scope ::= open enables declist ; statementlist BEGIN PushListV[top+4]; t1 ← PopTree[]; PushListV[top+2]; PushTree[t1]; IF BoolV[top+1] THEN { PushNode[block,2]; SetAttr[1,checked]; SetAttr[2,checked]; LinkToSource[top+2]; PushNode[enable,2]; LinkToSource[top+1]; SetBoolV[top,FALSE]} ELSE SetBoolV[top,TRUE]; END; 132 => -- binditem ::= exp {PushHash[Symbols.nullName]; PushNode[item,-2]; LinkToSource[top]}; 133 => -- binditem ::= id : exp -- binditem ::= id ~ ~ exp {PushHashV[top]; PushNode[item,-2]; LinkToSource[top]}; 134 => -- exits ::= EXITS exitlist {PushListV[top+1]; SetBoolV[top,TRUE]}; 135 => -- casestmtitem ::= caselabel => statement -- caseexpitem ::= caselabel => exp -- exititem ::= idlist => statement {PushNode[item,2]; LinkToSource[top]}; 136 => -- casetest ::= optrelation {PushTree[Tree.Null]; PushNodeV[top,-2]}; 137 => -- casetest ::= exp {PushTree[Tree.Null]; PushNode[relE,-2]}; 138 => -- caselabel ::= ident typeexp -- controlid ::= ident typeexp BEGIN PushTree[Tree.Null]; PushNode[cast,1]; PushNode[decl,3]; LinkToSource[top]; SetAttrs[FALSE,public,FALSE]; END; 139 => -- forclause ::= FOR controlid ← exp , exp PushNode[forseq,3]; 140 => -- forclause ::= FOR controlid direction IN range {PushTree[Tree.Null]; PushNodeV[top+2,3]}; 141 => -- forclause ::= THROUGH range {InsertTree[Tree.Null,2]; PushTree[Tree.Null]; PushNode[upthru,-3]}; 142 => -- direction ::= DECREASING SetOpV[top,downthru]; 143 => -- direction ::= SetOpV[top,upthru]; 144 => -- dotest ::= UNTIL exp PushNode[not,1]; 145 => -- doexit ::= {PushTree[Tree.Null]; PushTree[Tree.Null]}; 146 => -- doexit ::= REPEAT exitlist {PushListV[top+1]; PushTree[Tree.Null]}; 147 => -- doexit ::= REPEAT exitlist FINISHED => statement -- doexit ::= REPEAT exitlist FINISHED => statement ; {t1 ← PopTree[]; PushListV[top+1]; PushTree[t1]}; 148 => -- enables ::= ENABLE catchcase ; {PushTree[Tree.Null]; PushNode[catch,2]; SetBoolV[top,TRUE]}; 149 => -- enables ::= ENABLE catchany ; {PushTree[Tree.Null]; PushNode[catch,-2]; SetBoolV[top,TRUE]}; 150 => -- enables ::= ENABLE BEGIN catchlist END ; -- enables ::= ENABLE { catchlist } ; BEGIN t1 ← PopTree[]; PushListV[top+2]; PushTree[t1]; PushNode[catch,2]; SetBoolV[top,TRUE]; END; 151 => -- catchlist ::= catchhead catchcase {v[top].s ← v[top].s + 1; PushTree[Tree.Null]}; 152 => -- catchcase ::= lhslist => statement BEGIN t1 ← PopTree[]; PushListV[top]; PushTree[t1]; PushNode[item,2]; LinkToSource[top]; END; 153 => -- optargs ::= [ explist ] BEGIN t1 ← PopTree[]; IF t1 = Tree.Null THEN PushProperList[0] ELSE PushTree[t1]; SetBoolV[top,FALSE]; END; 154 => -- optargs ::= {PushTree[Tree.Null]; l[top] ← P1.InputLoc[]; SetBoolV[top,FALSE]}; 155 => -- transfer ::= SIGNAL SetOpV[top,signal]; 156 => -- transfer ::= ERROR SetOpV[top,error]; 157 => -- transfer ::= RETURN WITH ERROR SetOpV[top,xerror]; 158 => -- transfer ::= START SetOpV[top,start]; 159 => -- transfer ::= RESTART SetOpV[top,restart]; 160 => -- transfer ::= JOIN SetOpV[top,join]; 161 => -- transfer ::= NOTIFY SetOpV[top,notify]; 162 => -- transfer ::= BROADCAST SetOpV[top,broadcast]; 163 => -- transfer ::= TRANSFER WITH SetOpV[top,lste]; 164 => -- transfer ::= RETURN WITH SetOpV[top,lstf]; -- expression processing 165 => -- keyitem ::= id ~ optexp -- keyitem ::= id : optexp {PushHashV[top]; PushNode[item,-2]}; 166 => -- defaultopt ::= trash -- optexp ::= trash -- initvalue ::= trash PushNode[void,0]; 167 => -- defaultopt ::= exp '| trash {PushNode[void,0]; PushList[2]}; 168 => -- exp ::= IF exp THEN exp ELSE exp PushNode[ifx,3]; 169 => -- exp ::= casehead caseexplist ENDCASE => exp BEGIN t1 ← PopTree[]; PushProperListV[top+1]; PushTree[t1]; IF BoolV[top] THEN PushNode[bindx,4] ELSE PushNode[casex,3]; LinkToSource[top]; END; 170 => -- exp ::= lhs ← exp PushNode[assignx,2]; 171 => -- exp ::= [ explist ] ← exp PushNode[extractx,2]; 172 => -- exp ::= ERROR PushNode[syserrorx,0]; 173 => -- disjunct ::= disjunct OR conjunct PushNode[or,2]; 174 => -- conjunct ::= conjunct AND negation PushNode[and,2]; 175 => -- negation ::= ~ relation -- negation ::= NOT relation PushNode[not,1]; 176 => -- relation ::= sum optrelation -- sum ::= sum addop product -- product ::= product multop factor PushNodeV[top+1,2]; 177 => -- optrelation ::= NOT relationtail SetOpV[top, NegatedV[top+1]]; 178 => -- relationtail ::= IN range SetOpV[top,in]; 179 => -- relop ::= = SetOpV[top,relE]; 180 => -- relop ::= # SetOpV[top,relN]; 181 => -- relop ::= < SetOpV[top,relL]; 182 => -- relop ::= <= SetOpV[top,relLE]; 183 => -- relop ::= > SetOpV[top,relG]; 184 => -- relop ::= >= SetOpV[top,relGE]; 185 => -- addop ::= + SetOpV[top,plus]; 186 => -- addop ::= - SetOpV[top,minus]; 187 => -- multop ::= * SetOpV[top,times]; 188 => -- multop ::= / SetOpV[top,div]; 189 => -- multop ::= MOD SetOpV[top,mod]; 190 => -- factor ::= addop primary IF OpV[top] = minus THEN PushNode[uminus,1]; 191 => -- primary ::= [ explist ] {PushTree[Tree.Null]; PushNode[apply,-2]; SetAttr[1, FALSE]}; 192 => -- primary ::= prefixop [ orderlist ] {PushListV[top+2]; PushNodeV[top,1]}; 193 => -- primary ::= VAL [ orderlist ] {PushListV[top+2]; PushNode[val,1]}; 194 => -- primary ::= ALL [ orderlist ] {PushListV[top+2]; PushNode[all,1]}; 195 => -- primary ::= new [ typeexp initialization optcatch ] {PushNode[new, IF BoolV[top+4] THEN 4 ELSE 3]; SetAttrV[1,top+3]}; 196 => -- primary ::= cons [ explist optcatch ] PushNode[cons, IF BoolV[top+3] THEN 3 ELSE 2]; 197 => -- primary ::= listcons [ explist ] PushNode[listcons,2]; 198 => -- primary ::= NIL {PushTree[Tree.Null]; PushNode[nil,1]}; 199 => -- primary ::= typeop [ typeexp ] -- exp ::= transferop lhs PushNodeV[top,1]; 200 => -- qualifier ::= . prefixop -- qualifier ::= . typeop PushNodeV[top+1,1]; 201 => -- primary ::= SIZE [ typeexp ] -- qualifier ::= . SIZE {PushTree[Tree.Null]; PushNode[size,2]}; 202 => -- primary ::= SIZE [ typeexp , exp ] PushNode[size,2]; 203 => -- primary ::= ISTYPE [ exp , typeexp ] PushNode[istype,2]; 204 => -- primary ::= @ lhs PushNode[addr,1]; 205 => -- primary ::= DESCRIPTOR [ desclist ] PushNode[arraydesc,1]; 206 => -- lhs ::= id -- element ::= id -- ident ::= id : -- controlid ::= id PushHashV[top]; 207 => -- lhs ::= num -- lhs ::= string PushLitV[top]; 208 => -- lhs ::= lnum {PushLitV[top]; PushNode[mwconst,1]; SetAttr[1,FALSE]}; 209 => -- lhs ::= flnum {PushLitV[top]; PushNode[mwconst,1]; SetAttr[1,TRUE]}; 210 => -- lhs ::= char {PushLitV[top]; PushNode[clit,1]}; 211 => -- lhs ::= lstring {PushLitV[top]; PushNode[llit,1]}; 212 => -- lhs ::= atom {PushHashV[top]; PushNode[atom,1]}; 213 => -- lhs ::= NARROW [ exp opttype optcatch ] PushNode[narrow, IF BoolV[top+4] THEN 3 ELSE 2]; 214 => -- lhs ::= LOOPHOLE [ exp opttype ] PushNode[loophole,2]; 215 => -- lhs ::= APPLY [ exp , exp optcatch ] {PushNode[apply, IF BoolV[top+5] THEN 3 ELSE 2]; SetAttr[1,TRUE]}; 216 => -- qualifier ::= [ explist optcatch ] {PushNode[apply, IF BoolV[top+2] THEN 3 ELSE 2]; SetAttr[1,FALSE]}; 217 => -- qualifier ::= . id {PushHashV[top+1]; PushNode[dot,2]}; 218 => -- qualifier ::= ↑ PushNode[uparrow,1]; 219 => -- optcatch ::= ! catchlist BEGIN t1 ← PopTree[]; PushListV[top+1]; PushTree[t1]; PushNode[catch,2]; SetBoolV[top,TRUE]; END; 220 => -- transferop ::= SIGNAL SetOpV[top,signalx]; 221 => -- transferop ::= ERROR SetOpV[top,errorx]; 222 => -- transferop ::= START SetOpV[top,startx]; 223 => -- transferop ::= JOIN SetOpV[top,joinx]; 224 => -- transferop ::= NEW SetOpV[top,create]; 225 => -- transferop ::= FORK SetOpV[top,fork]; 226 => -- prefixop ::= LONG SetOpV[top,lengthen]; 227 => -- prefixop ::= ABS SetOpV[top,abs]; 228 => -- prefixop ::= PRED SetOpV[top,pred]; 229 => -- prefixop ::= SUCC SetOpV[top,succ]; 230 => -- prefixop ::= ORD SetOpV[top,ord]; 231 => -- prefixop ::= MIN SetOpV[top,min]; 232 => -- prefixop ::= MAX SetOpV[top,max]; 233 => -- prefixop ::= BASE SetOpV[top,base]; 234 => -- prefixop ::= LENGTH SetOpV[top,length]; 235 => -- typeop ::= CODE SetOpV[top,typecode]; 236 => -- typeop ::= FIRST SetOpV[top,first]; 237 => -- typeop ::= LAST SetOpV[top,last]; 238 => -- typeop ::= NIL SetOpV[top,nil]; 239 => -- desclist ::= exp , exp opttype PushList[3]; 240 => -- directory ::= DIRECTORY ; -- imports ::= IMPORTS -- exports ::= EXPORTS -- fieldlist ::= [ ] -- new ::= NEW -- free ::= FREE -- cons ::= CONS -- listcons ::= LIST -- pointerprefix ::= POINTER -- catchlist ::= catchhead PushTree[Tree.Null]; 241 => -- using ::= USING [ ] -- defaultopt ::= PushProperList[0]; 242 => -- elementlist ::= -- statementlist ::= -- casestmtlist ::= -- exitlist ::= -- catchhead ::= -- caseexplist ::= v[top].s ← 0; 243 => -- includelist ::= includeitem -- modulelist ::= moduleitem -- declist ::= declaration -- pairlist ::= pairitem -- elementlist' ::= element -- variantlist ::= variantitem -- bindlist ::= binditem -- statementlist' ::= statement -- casestmtlist' ::= casestmtitem -- caselabel' ::= casetest -- exitlist' ::= exititem -- lhslist ::= lhs -- orderlist ::= optexp -- keylist ::= keyitem -- caseexplist' ::= caseexpitem v[top].s ← 1; 244 => -- includelist ::= includelist , includeitem -- modulelist ::= modulelist , moduleitem -- declist ::= declist ; declaration -- pairlist ::= pairlist , pairitem -- elementlist' ::= elementlist' , element -- 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 v[top].s ← v[top].s+1; 245 => -- idlist ::= idlist' -- identlist ::= identlist' -- explist ::= orderlist -- explist ::= keylist -- caselabel ::= caselabel' PushListV[top]; 246 => -- directory ::= DIRECTORY includelist ; -- imports ::= IMPORTS modulelist -- exports ::= EXPORTS modulelist -- open ::= OPEN bindlist ; -- fieldlist ::= [ pairlist ] -- fieldlist ::= [ typelist ] PushListV[top+1]; 247 => -- class ::= PROGRAM -- safe ::= UNSAFE -- initialization ::= ← initvalue -- casehead ::= SELECT exp FROM SetBoolV[top,FALSE]; 248 => -- class ::= MONITOR -- packed ::= PACKED -- safe ::= SAFE -- readonly ::= READONLY -- reclist ::= [ variantpair ] -- ordered ::= ORDERED -- base ::= BASE -- heap ::= UNCOUNTED -- initialization ::= tilde initvalue -- inline ::= INLINE -- optargs ::= lhs -- casehead ::= WITH binditem SELECT optexp FROM SetBoolV[top,TRUE]; 249 => -- packed ::= -- readonly ::= -- monitored ::= -- ordered ::= -- base ::= -- heap ::= -- inline ::= -- enables ::= -- exits ::= -- optcatch ::= {SetBoolV[top,FALSE]; l[top] ← P1.InputLoc[]}; 250 => -- using ::= USING [ idlist ] -- interface ::= imports exports shares -- shares ::= SHARES idlist -- tilde ::= ~ -- tilde ::= = -- typeid ::= typeid' -- typeexp ::= typeid -- typeexp ::= typecons -- typecons ::= typeappl -- optsize ::= [ exp ] -- elementlist ::= elementlist' -- length ::= [ exp ] -- default ::= ← defaultopt -- defaultopt ::= exp -- tagtype ::= typeexp -- pointerprefix ::= POINTER interval -- indextype ::= typeexp -- arguments ::= arglist returnlist -- arglist ::= fieldlist -- returnlist ::= RETURNS fieldlist -- initvalue ::= exp -- statement ::= basicstmt -- balstmt ::= basicstmt -- dotest ::= WHILE exp -- catchany ::= ANY => statement -- catchlist ::= catchhead catchany -- catchlist ::= catchhead catchany ; -- statementlist ::= statementlist' -- statementlist ::= statementlist' ; -- casestmtlist ::= casestmtlist' -- casestmtlist ::= casestmtlist' ; -- exitlist ::= exitlist' -- exitlist ::= exitlist' ; -- caseexplist ::= caseexplist' -- caseexplist ::= caseexplist' , -- trash ::= TRASH -- trash ::= NULL -- optexp ::= exp -- exp ::= disjunct -- disjunct ::=C conjunct -- conjunct ::=C negation -- negation ::=C relation -- relation ::= sum -- optrelation ::= relationtail -- relationtail ::= relop sum -- range ::= interval -- range ::= typeid -- bounds ::= exp .. exp -- sum ::=C product -- product ::=C factor -- factor ::=C primary -- primary ::= lhs -- desclist ::= exp -- lhs ::= ( exp ) -- lhs ::= lhs qualifier -- new ::= lhs . NEW -- free ::= lhs . FREE -- cons ::= lhs . CONS -- listcons ::= lhs . LIST -- opttype ::= , typeexp NULL; 251 => -- directory ::= -- using ::= -- locks ::= -- lambda ::= -- imports ::= -- exports ::= -- shares ::= -- optsize ::= -- optbits ::= -- default ::= -- open ::= -- arglist ::= -- returnlist ::= -- indextype ::= -- forclause ::= -- dotest ::= -- optexp ::= -- opttype ::= {PushTree[Tree.Null]; l[top] ← P1.InputLoc[]}; 252 => -- checked ::= {SetBoolV[top,checked]; trusted ← checked}; 253 => -- checked ::= CHECKED {SetBoolV[top,checked]; trusted ← checked ← TRUE}; 254 => -- checked ::= TRUSTED {SetBoolV[top,checked]; trusted ← TRUE; checked ← FALSE}; 255 => -- checked ::= UNCHECKED {SetBoolV[top,checked]; trusted ← checked ← FALSE}; -- error or unimplemented ENDCASE => ERROR; ENDLOOP}; }.