-- file BcdTreeBuild.mesa rewritten by PGS, 10-Jan-83 14:22
-- last edited by Satterthwaite on January 10, 1983 2:26 pm
-- last edited by Lewis on 12-Mar-81 18:04:07
DIRECTORY
P1: TYPE USING [
ActionStack, LinkStack, Value, ValueStack, InputLoc, nullId, nullValue],
ParseTable: TYPE USING [ProdDataRef, Symbol, tokenID],
Tree: TYPE USING [Link, null],
TreeOps: TYPE USING [
PopTree, PushTree, PushHash, PushList, PushNode, SetAttr, SetInfo];
BcdTreeBuild: PROGRAM
IMPORTS P1, TreeOps
EXPORTS P1 = {
OPEN TreeOps;
-- local data base (supplied by parser)
v: P1.ValueStack;
l: P1.LinkStack;
q: P1.ActionStack;
proddata: ParseTable.ProdDataRef;
AssignDescriptors: PUBLIC PROC [
qd: P1.ActionStack, vd: P1.ValueStack, ld: P1.LinkStack, pp: ParseTable.ProdDataRef] ~
{q ← qd; v ← vd; l ← ld; proddata ← pp};
-- the interpretation rules
LinkToSource: PROC [index: CARDINAL] ~ 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;
SetLinkAttrs: PROC ~ {
SetAttr[$codeLinks, linkSpec IN CodeLinks];
SetAttr[$explicitLinkLoc, linkSpec # DefaultLinks[linkSpec]]};
ProcessQueue: PUBLIC PROC [qI, top: CARDINAL] ~ {
save: Tree.Link;
vTop: P1.Value;
FOR i: CARDINAL IN [0 .. qI) DO
top ← top-q[i].tag.pLength+1; vTop ← v[top];
SELECT proddata[q[i].transition].rule FROM
0 => --
--TABLE: BcdParseData TYPE: ParseTable EXPORTS: SELF
--GOAL: goal
--TERMINALS:
-- id str , ;
-- : ← = ~
-- ] [ } { .
-- DIRECTORY FROM PACK CONFIGURATION CONFIG
-- IMPORTS EXPORTS CONTROL BEGIN
-- 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
BEGIN
PushHash[v[top].r]; PushHash[v[top+3].r]; PushNode[$item,2];
LinkToSource[top];
END;
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 control tilde body
-- config ::= id : CONFIGURATION links imports exports control tilde body
BEGIN
save ← PopTree[];
PushHash[v[top].r]; PushTree[save]; PushNode[$config,5];
SetAttr[$exportsALL, exportsALL]; LinkToSource[top];
linkSpec ← v[top+3].s; exportsALL ← v[top+5].s; -- restore old values
END;
9 => -- links ::=
{vTop ← [scalar[linkSpec]]; linkSpec ← DefaultLinks[linkSpec]};
10 => -- links ::= LINKS : CODE
{vTop ← [scalar[linkSpec]]; linkSpec ← $code};
11 => -- links ::= LINKS : FRAME
{vTop ← [scalar[linkSpec]]; 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
BEGIN
SetLinkAttrs[];
PushTree[Tree.null]; PushNode[$module,2];
SetLinkAttrs[]; LinkToSource[top];
linkSpec ← v[top+1].s;
END;
17 => -- module ::= item [ ] links
BEGIN
SetLinkAttrs[];
PushTree[Tree.null]; PushNode[$module,2];
SetLinkAttrs[]; LinkToSource[top];
linkSpec ← v[top+3].s;
END;
18 => -- module ::= item [ idlist ] links
BEGIN
PushList[v[top+2].s]; save ← PopTree[];
SetLinkAttrs[];
PushTree[save]; PushNode[$module,2];
SetLinkAttrs[]; LinkToSource[top];
linkSpec ← v[top+4].s;
END;
19 => -- interface ::= id
PushHash[v[top].r];
20 => -- interface ::= interface THEN id
{PushHash[v[top+2].r]; PushNode[$then,2]; LinkToSource[top]};
21 => -- interface ::= interface PLUS id
{PushHash[v[top+2].r]; PushNode[$plus,2]; LinkToSource[top]};
22 => -- item ::= id
BEGIN
PushHash[v[top].r]; PushTree[Tree.null]; PushNode[$item,2];
LinkToSource[top];
END;
23 => -- item ::= id : id
BEGIN
PushHash[v[top].r]; PushHash[v[top+2].r]; PushNode[$item,2];
LinkToSource[top];
END;
24 => -- idlist ::= id
{PushHash[v[top].r]; vTop ← [scalar[1]]};
25 => -- idlist ::= idlist , id
{PushHash[v[top+2].r]; vTop ← [scalar[v[top].s+1]]};
26 => -- tilde ::= ~
-- tilde ::= =
-- statementlist ::= statementlist ;
-- statement ::= module
-- statement ::= config
-- leftside ::= item
NULL;
27 => -- imports ::=
-- control ::=
-- directory ::=
-- packing ::=
{PushTree[Tree.null]; l[top] ← P1.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[Tree.null]; l[top] ← P1.InputLoc[]; vTop ← [scalar[exportsALL]]};
32 => -- expinit ::=
{vTop ← [scalar[exportsALL]]; 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]};
ENDCASE => ERROR;
v[top] ← vTop;
ENDLOOP};
TokenValue: PUBLIC PROC [s: ParseTable.Symbol] RETURNS [P1.Value] ~ {
RETURN [SELECT s FROM
ParseTable.tokenID => P1.nullId,
ENDCASE => P1.nullValue]};
}.