MobSEBuild.mesa
Copyright Ó 1985, 1989, 1991 by Xerox Corporation. All rights reserved.
Satterthwaite on March 14, 1986 11:53:21 am PST
Lewis on 17-Dec-80 16:30:26
Maxwell, August 11, 1983 2:46 pm
Russ Atkinson (RRA) March 7, 1985 0:16:28 am PST
Andy Litman March 21, 1988 11:08:24 pm PST
JKF July 22, 1989 3:55:56 pm PDT
DIRECTORY
Alloc USING [AddNotify, DropNotify, Notifier],
MobComData USING [data],
MobControlDefs USING [],
MobDefs USING [cttype, cxtype, FTIndex, FTNull, NameRecord, sttype, treetype],
MobUtilDefs USING [EnterFile, NameForSti, NewContext, NewSemanticEntry],
MobCommandUtil USING [GetNthPair, ListLength],
ConvertUnsafe USING [SubString, SubStringToRope],
MobHashOps USING [EnterString, SubStringForHash],
Rope USING [Flatten, Length, ROPE],
MobSymbols USING [CXIndex, HTIndex, STIndex, stNull],
Table USING [Base],
MobTree USING [Index, Link, Map, null, ConfigSons],
MobTreeOps USING [FreeNode, GetNode, UpdateList];
MobSEBuild: PROGRAM
IMPORTS Alloc, MobUtilDefs, MobCommandUtil, ConvertUnsafe, MobHashOps, Rope, MobTreeOps, MobComData
EXPORTS MobControlDefs = {
OPEN MobDefs, MobSymbols, MobComData;
Sons: TYPE = MobTree.ConfigSons;
BuildSEError: PUBLIC ERROR ~ CODE;
tb, stb, ctb, cxb: Table.Base;
Notifier: Alloc.Notifier ~ {
tb ¬ base[treetype]; stb ¬ base[sttype];
cxb ¬ base[cxtype]; ctb ¬ base[cttype]};
currentCtx, directoryCtx: CXIndex;
BuildSemanticEntries: PUBLIC PROC[root: MobTree.Link] ~ {
node: MobTree.Index;
(data.table).AddNotify[Notifier];
node ¬ MobTreeOps.GetNode[root];
IF tb[node].name # $source THEN ERROR BuildSEError;
currentCtx ¬ directoryCtx ¬ MobUtilDefs.NewContext[];
IF (data.commandArgs).ListLength > 0 THEN EnterArgsAsDirItems[];
tb[node].son[1] ¬ MobTreeOps.UpdateList[tb[node].son[1], DirItem];
currentCtx ¬ MobUtilDefs.NewContext[];
tb[node].son[2] ¬ MobTreeOps.UpdateList[tb[node].son[2], PackId];
currentCtx ¬ MobUtilDefs.NewContext[];
tb[node].son[3] ¬ Stmt[tb[node].son[3]];
(data.table).DropNotify[Notifier]};
Stmt: MobTree.Map ~ {
WITH t SELECT FROM
hash => v ¬ Item[t];
symbol => v ¬ Item[t];
subtree => {
node: MobTree.Index ~ index;
saveIndex: CARDINAL ~ data.textIndex;
data.textIndex ¬ tb[node].info;
v ¬ SELECT tb[node].name FROM
$list => MobTreeOps.UpdateList[t, Stmt],
$item => Item[t],
$config => Config[node],
$assign => Assign[node],
$plus, $then => Expression[t],
$module => Module[node],
ENDCASE => ERROR BuildSEError;
data.textIndex ¬ saveIndex};
ENDCASE => ERROR BuildSEError;
RETURN};
PackId: MobTree.Map ~ {
RETURN [WITH t SELECT FROM
hash => SemanticEntry[t],
subtree => MobTreeOps.UpdateList[t, PackId],
ENDCASE => ERROR BuildSEError]
};
ProcessItem: PROC[t: MobTree.Link] RETURNS[tl: MobTree.Link, st1,st2: STIndex] ~ {
stl: MobTree.Link.symbol;
st2 ¬ stNull;
WITH tt~~t SELECT FROM
symbol => {tl ¬ tt; st1 ¬ tt.index};
hash => {tl ¬ stl ¬ SemanticEntry[t]; st1 ¬ stl.index};
subtree => {
OPEN tb[tt.index];
tl ¬ t;
son[1] ¬ stl ¬ SemanticEntry[son[1]]; st1 ¬ stl.index;
IF son[2] # MobTree.null THEN {
stb[st1].filename ¬ FALSE;
son[2] ¬ stl ¬ SemanticEntry[son[2]]; st2 ¬ stl.index;
stb[st1].body ¬ external[pointer~instance[st2], map~[unknown[]]]}};
ENDCASE => ERROR BuildSEError;
RETURN};
SetFilename: PROC[sti: STIndex] ~ {
OPEN stb[sti];
IF ~stb[sti].filename AND stb[sti].type = $unknown THEN {
stb[sti].filename ¬ TRUE;
stb[sti].body ¬ external[pointer~file[FTNull], map~[unknown[]]]}
};
Item: MobTree.Map ~ {
st1, st2: STIndex;
[v, st1, st2] ¬ ProcessItem[t];
SetFilename[IF st2 = stNull THEN st1 ELSE st2];
RETURN};
EnterArgsAsDirItems: PROC ~ {
enter Idi: FileNamei pairs from command line as DIRECTORY entries
lhs, rhs: Rope.ROPE;
lhsHti: MobSymbols.HTIndex;
sti, last: MobSymbols.STIndex;
rhsFti: MobDefs.FTIndex;
ss: ConvertUnsafe.SubString;
FOR n: CARDINAL IN [0 .. (data.commandArgs).ListLength) DO {
[lhs, rhs] ¬ (data.commandArgs).GetNthPair[n];
ss.offset ¬ 0;
ss.length ¬ lhs.Length[];
ss.base ¬ LOOPHOLE[lhs.Flatten[]];
lhsHti ¬ MobHashOps.EnterString[ss];
last ¬ MobSymbols.stNull;
FOR sti ¬ cxb[directoryCtx].link, stb[sti].link UNTIL sti = MobSymbols.stNull DO
IF stb[sti].hti = lhsHti THEN GOTO AlreadyEntered;
last ¬ sti;
ENDLOOP;
sti ¬ MobUtilDefs.NewSemanticEntry[lhsHti];
IF last = MobSymbols.stNull THEN cxb[directoryCtx].link ¬ sti
ELSE stb[last].link ¬ sti;
rhsFti ¬ MobUtilDefs.EnterFile[LOOPHOLE[rhs.Flatten[]]];
stb[sti].body ¬ external[map~[unknown[]], pointer~file[rhsFti]];
EXITS
AlreadyEntered => NULL};
ENDLOOP
};
DirItem: MobTree.Map ~ {
lhs: MobTree.Link;
lhsHti: MobSymbols.HTIndex;
dirSti, sti: STIndex;
stl: MobTree.Link.symbol;
fti: FTIndex;
fileName: Rope.ROPE;
name: ConvertUnsafe.SubString;
WITH t SELECT FROM
subtree => {
lhs ¬ tb[index].son[1];
WITH lhs SELECT FROM
hash => lhsHti ¬ index;
ENDCASE => ERROR BuildSEError;
FOR dirSti ¬ cxb[directoryCtx].link, stb[dirSti].link UNTIL dirSti = MobSymbols.stNull DO
IF stb[dirSti].hti = lhsHti THEN RETURN [t]; -- already inserted
ENDLOOP;
stl ¬ SemanticEntry[lhs];
sti ¬ stl.index;
WITH s2~~tb[index].son[2] SELECT FROM
hash => name ¬ MobHashOps.SubStringForHash[s2.index];
ENDCASE};
ENDCASE;
fileName ¬ name.SubStringToRope;
fti ¬ MobUtilDefs.EnterFile[LOOPHOLE[fileName.Flatten[]]];
stb[sti].body ¬ external[map~[unknown[]], pointer~file[fti]];
RETURN [t]};
ImpItem: MobTree.Map ~ {
st1: STIndex;
[v, st1, ] ¬ ProcessItem[t]; stb[st1].imported ¬ TRUE;
RETURN};
ExpItem: MobTree.Map ~ {
st1: STIndex;
[v, st1, ] ¬ ProcessItem[t]; stb[st1].exported ¬ TRUE;
RETURN};
Config: PROC[node: MobTree.Index] RETURNS[MobTree.Link] ~ {
OPEN tb[node];
saveCx: CXIndex ~ currentCtx;
saveName: NameRecord ~ data.currentName;
SeEntry: MobTree.Map ~ {RETURN [SemanticEntry[t]]};
EnterConfig[node]; -- name
son[Sons.imports.ORD] ¬ MobTreeOps.UpdateList[son[Sons.imports.ORD], ImpItem];
son[Sons.exports.ORD] ¬ MobTreeOps.UpdateList[son[Sons.exports.ORD], ExpItem];
son[Sons.control.ORD] ¬ MobTreeOps.UpdateList[son[Sons.control.ORD], SeEntry];
son[Sons.body.ORD] ¬ MobTreeOps.UpdateList[son[Sons.body.ORD], Stmt];
currentCtx ¬ saveCx; data.currentName ¬ saveName;
RETURN [[subtree[node]]]};
AssignItem: MobTree.Map ~ {
st1, st2: STIndex;
[v, st1, st2] ¬ ProcessItem[t];
stb[st1].assigned ¬ TRUE;
IF stb[st1].filename THEN {
OPEN stb[st1];
filename ¬ FALSE;
body ¬ external[pointer~instance[st2], map~[unknown[]]]};
IF st2 # stNull THEN {
OPEN stb[st2];
assigned ¬ TRUE;
filename ¬ FALSE;
body ¬ external[pointer~instance[stNull], map~[unknown[]]]};
RETURN};
Assign: PROC[node: MobTree.Index] RETURNS[MobTree.Link] ~ {
tb[node].son[1] ¬ MobTreeOps.UpdateList[tb[node].son[1], AssignItem];
tb[node].son[2] ¬ Expression[tb[node].son[2]];
RETURN [[subtree[node]]]};
Expression: MobTree.Map ~ {
WITH t SELECT FROM
symbol => v ¬ ProcessItem[t].tl;
hash => v ¬ ProcessItem[t].tl;
subtree =>
SELECT tb[index].name FROM
$item => v ¬ ProcessItem[t].tl;
$module => v ¬ Module[index];
$plus, $then => {
OPEN tb[index];
son[1] ¬ Expression[son[1]]; son[2] ¬ Expression[son[2]];
v ¬ t};
ENDCASE => ERROR BuildSEError;
ENDCASE => ERROR BuildSEError;
RETURN};
ModItem: MobTree.Map ~ {
RETURN [WITH t SELECT FROM
symbol => t,
hash => SemanticEntry[t],
ENDCASE => ERROR BuildSEError]};
Module: PROC[node: MobTree.Index] RETURNS[MobTree.Link] ~ {
tb[node].son[1] ¬ Item[tb[node].son[1]];
tb[node].son[2] ¬ MobTreeOps.UpdateList[tb[node].son[2], ModItem];
RETURN [[subtree[node]]]};
SemanticEntry: PROC[tl: MobTree.Link] RETURNS[MobTree.Link.symbol] ~ {
sti, dirSti: STIndex;
last: STIndex ¬ stNull;
WITH t~~tl SELECT FROM
symbol => RETURN [t];
hash => {
FOR sti ¬ cxb[currentCtx].link, stb[sti].link UNTIL sti = stNull DO
IF stb[sti].hti = t.index THEN RETURN [[symbol[sti]]];
last ¬ sti;
ENDLOOP;
FOR dirSti ¬ cxb[directoryCtx].link, stb[dirSti].link UNTIL dirSti = stNull DO
IF stb[dirSti].hti = t.index THEN EXIT ENDLOOP;
sti ¬ MobUtilDefs.NewSemanticEntry[t.index];
IF last = stNull THEN cxb[currentCtx].link ¬ sti
ELSE stb[last].link ¬ sti;
IF dirSti # stNull THEN {stb[sti] ¬ stb[dirSti]; stb[sti].link ¬ stNull};
RETURN [[symbol[sti]]]};
subtree => {
node: MobTree.Index ~ t.index;
l: MobTree.Link;
SELECT tb[node].name FROM
$dot => {l ¬ tb[node].son[1]; tb[node].son[1] ¬ MobTree.null};
$slash => {l ¬ tb[node].son[2]; tb[node].son[2] ¬ MobTree.null};
ENDCASE => ERROR BuildSEError;
MobTreeOps.FreeNode[node];
RETURN [SemanticEntry[l]]};
ENDCASE => ERROR BuildSEError};
EnterConfig: PROC[node: MobTree.Index] ~ {
sti: STIndex;
stl: MobTree.Link.symbol ~ SemanticEntry[tb[node].son[Sons.name.ORD]];
tb[node].son[Sons.name.ORD] ¬ stl;
stb[(sti ¬ stl.index)].filename ¬ FALSE;
currentCtx ¬ MobUtilDefs.NewContext[];
data.currentName ¬ MobUtilDefs.NameForSti[sti];
SELECT stb[sti].type FROM
$unknown => stb[sti].body ¬ local[info~node, context~currentCtx, map~[unknown[]]];
ENDCASE => ERROR BuildSEError
};
}.