-- 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};
}.