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 ~ { 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 }; }. Ž 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 enter Idi: FileNamei pairs from command line as DIRECTORY entries ΚM•NewlineDelimiter –(cedarcode) style™codešœ™Kšœ Οeœ=™HKšΟy/™/Kšž™Kšž ™ K™0Kšž*™*K™ K™—šΟk ˜ KšœŸœ#˜.Kšœ Ÿœ˜KšœŸœ˜KšœŸœA˜NKšœ Ÿœ7˜HKšœŸœ˜.KšœŸœ˜1Kšœ Ÿœ!˜1KšœŸœŸœ˜#Kšœ Ÿœ%˜5KšœŸœ˜KšœŸœ&˜3Kšœ Ÿœ!˜1K˜—šœ Ÿ˜KšŸ œ]˜fKšŸ œ˜KšŸœ!˜%K˜K˜ KšœŸœŸœŸœ˜"K˜K˜K˜˜K˜+K˜(K˜K˜—K˜"K˜šΟnœŸœŸœ˜9K˜K˜!K˜ KšŸœŸœŸœ˜3K˜5KšŸœ#Ÿœ˜@K˜BK˜&K˜AK˜&K˜(K˜#K˜—˜šŸœŸœŸ˜K˜K˜˜ K˜Kšœ Ÿœ˜%K˜šœŸœŸ˜K˜+K˜K˜K˜K˜K˜KšŸœŸœ˜—K˜—KšŸœŸœ˜—KšŸœ˜K˜—˜šŸœŸœŸœŸ˜K˜K˜,KšŸœŸœ˜—šœ˜K˜——š  œŸœŸœ(˜RK˜K˜ šŸœŸœŸ˜K˜$K˜7˜ KšŸœ˜K˜K˜7šŸœŸœ˜KšœŸœ˜K˜7K˜C——KšŸœŸœ˜—KšŸœ˜K˜—š  œŸœ˜#KšŸœ ˜šŸœŸœŸœ˜9KšœŸœ˜K˜@—˜K˜——˜K˜K˜Kšœ ŸœŸœŸœ˜/KšŸœ˜ K˜—š œŸœ˜KšœA™AKšœŸœ˜K˜K˜K˜K˜šŸœŸœŸœ&Ÿœ˜K˜@KšŸœŸœ˜—K˜KšŸœ˜—KšŸœŸœ˜K˜——š  œŸœ˜*K˜ K˜FK˜"Kšœ"Ÿœ˜(K˜&K˜/šŸœŸ˜K˜RKšŸœŸœ ˜—šœ˜K˜——K˜K˜——…— φ*Ρ