DIRECTORY Ascii USING [CR, NUL, SP, TAB], BasicTime USING [GMT--, ToPupTime--], BcdDefs USING [CTHandle, FPHandle, MTHandle, SPHandle], ConvertUnsafe USING [AppendRope], DateAndTime USING [Notes, Parse, Unintelligible], FileIO USING [Open], IO USING [ card, char, CharProc, Close, CreateFilterCommentsStream, EndOfStream, GetCard, GetChar, GetId, GetIndex, GetSequence, PutChar, PutF, PutFR, PutRope, RIS, rope, SkipOver, STREAM, SyntaxError, time], MB USING [ Abort, BHandle, DoAllBCDs, DoAllFramePacks, DoAllSpaces, DoAllTopLevelConfigs, Error, GetFrameWeight, GetFsiChain, Handle, InstanceToMTHandle, ListType, NameToCTHandle, NameToFPHandle, NameToG, NameToMTHandle, DoAllModules, NameToSPHandle, ResetConfig, SetConfig, SetFrameWeight, SetFsiChain], PrincOps USING [ FrameSizeIndex, FrameVec, GFTIndex, GlobalFrameHandle, Priority, PsbIndex, StateVector, wordsPerPage], Rope USING [Cat, Concat, Equal, FromChar, ROPE], Segments USING [FHandle, FileNameProblem, GetFileTimes, NewFile], SystemVersion USING [Date], Time USING [Packed]; MBParse: PROGRAM IMPORTS --BasicTime, --ConvertUnsafe, DateAndTime, FileIO, IO, MB, Rope, Segments EXPORTS MB = BEGIN OPEN MB; ROPE: TYPE = Rope.ROPE; data: MB.Handle _ NIL; source: IO.STREAM _ NIL; noTrapList: Node; controlList: Node; stateLists: ARRAY ListType OF Node; -- circularly linked, pointer is to last element wartConfig, wartModule: ROPE; Node: TYPE = REF Item; Item: TYPE = RECORD [ link: Node, body: SELECT type: * FROM name => [name: ROPE], dot => [module, instance: ROPE], config => [name: ROPE, list: Node], space => [list: Node], frame => [list: Node], globalframe => [list: Node], code => [list: Node], bcd => [list: Node], ENDCASE ]; Separator: TYPE = {semiColon, colon, comma, openBracket, closeBracket, dot}; Keyword: TYPE = { resident, resDesc, in, frame, framepack, space, codepack, globalFrame, code, bcd, wart, noTrap, control, frameweight, framecount, gft, mdsbase, codebase, pdapages, framePages, processes, svSize, nSV, all, version, uCodeDolphin, uCodeDorado, uCodeDandelion, uCodeDicentra}; keywords: ARRAY Keyword OF ROPE = [ "RESIDENT", "RESIDENTDESCRIPTOR", "IN", "FRAME", "FRAMEPACK", "SPACE", "CODEPACK", "GLOBALFRAME", "CODE", "BCD", "WART", "NOTRAP", "CONTROL", "FRAMEWEIGHT", "FRAMECOUNT", "GFT", "MDSBASE", "CODEBASE", "PDAPAGES", "FRAMEPAGES", "PROCESSES", "STATEVECTORSIZE", "STATEVECTORCOUNT", "ALL", "VERSION", "UCODEDOLPHIN", "UCODEDORADO", "UCODEDANDELION", "UCODEDICENTRA"]; separators: ARRAY Separator OF CHAR = [';, ':, ',, '[, '], '.]; lastSep: CHARACTER; InputFile: TYPE = REF InputFileNode; InputFileNode: TYPE = RECORD [ next: InputFile _ NIL, name: ROPE, create: Time.Packed _ [0]]; inputFiles: InputFile _ NIL; -- circularly linked; pointer is to last element InitParse: PUBLIC PROC [h: MB.Handle] = { data _ h; ClearGlobals[]; }; FinishParse: PUBLIC PROC = { BreakCircularities: PROC = { UnloopList: PROC [tail: Node] = { p: Node _ tail; IF p = NIL THEN RETURN; DO p _ p.link; WITH p: p SELECT FROM name => NULL; dot => NULL; config => UnloopList[p.list]; space => UnloopList[p.list]; frame => UnloopList[p.list]; globalframe => UnloopList[p.list]; code => UnloopList[p.list]; bcd => UnloopList[p.list]; ENDCASE; IF p = tail THEN EXIT; ENDLOOP; tail.link _ NIL; }; IF inputFiles ~= NIL THEN inputFiles.next _ NIL; FOR list: ListType IN ListType DO UnloopList[stateLists[list]]; ENDLOOP; UnloopList[controlList]; UnloopList[noTrapList]; }; BreakCircularities[]; ClearGlobals[]; data _ NIL; }; ClearGlobals: PROC = { noTrapList _ NIL; controlList _ NIL; stateLists _ ALL[NIL]; wartConfig _ wartModule _ NIL; source _ NIL; inputFiles _ NIL; }; ProcessInput: PUBLIC PROC [file: ROPE] = { fileS: STRING _ [40]; fh: Segments.FHandle; inputFile: InputFile = NEW[InputFileNode _ [name: file]]; ConvertUnsafe.AppendRope[to: fileS, from: file]; fh _ Segments.NewFile[fileS ! Segments.FileNameProblem[] => Error["Parameter file not found!"]]; inputFile.create _ Segments.GetFileTimes[fh].create; source _ IO.CreateFilterCommentsStream[FileIO.Open[file]]; ParseInput[]; source.Close[]; -- note: assumed to close the backing stream IF inputFiles = NIL THEN inputFile.next _ inputFile ELSE {inputFile.next _ inputFiles.next; inputFiles.next _ inputFile}; inputFiles _ inputFile; }; EchoInput: PUBLIC PROC = { loadmap: IO.STREAM = data.loadmap; EchoList: PROC [tail: Node, topLevel: BOOL _ TRUE] = { p: Node _ tail; IF topLevel THEN loadmap.PutRope[" "] ELSE loadmap.PutChar['[]; IF p ~= NIL THEN DO p _ p.link; WITH p SELECT FROM name => loadmap.PutRope[name]; dot => loadmap.PutF["%g.%g", IO.rope[module], IO.rope[instance]]; config => {loadmap.PutRope[name]; EchoList[list, FALSE]}; space => {loadmap.PutRope[keywords[codepack]]; EchoList[list, FALSE]}; frame => {loadmap.PutRope[keywords[framepack]]; EchoList[list, FALSE]}; globalframe => {loadmap.PutRope[keywords[globalFrame]]; EchoList[list, FALSE]}; code => {loadmap.PutRope[keywords[code]]; EchoList[list, FALSE]}; bcd => {loadmap.PutRope[keywords[bcd]]; EchoList[list, FALSE]}; ENDCASE; IF p = tail THEN EXIT; loadmap.PutRope[IF topLevel THEN ",\N " ELSE ", "]; ENDLOOP; IF topLevel THEN loadmap.PutRope[";\N"] ELSE loadmap.PutChar[']]; }; IF inputFiles ~= NIL THEN { inputFile: InputFile _ inputFiles.next; loadmap.PutF["Parameter File%g:\N\N", IO.rope[IF inputFile ~= inputFiles THEN "s" ELSE NIL]]; DO loadmap.PutF[" %39j %t\N", IO.rope[inputFile.name], IO.time[inputFile.create]]; IF inputFile = inputFiles THEN EXIT; inputFile _ inputFile.next; ENDLOOP; loadmap.PutChar['\N]; }; loadmap.PutRope["Input Parameters:\N\N"]; loadmap.PutF[" Version = %d.%d%g\N", IO.card[data.header.release.major], IO.card[data.header.release.minor], IO.rope[ IF data.header.release.patch = 0 THEN NIL ELSE IO.PutFR[".%d", IO.card[data.header.release.patch]]] ]; loadmap.PutRope[" Earliest acceptable microcode:\N"]; IF data.header.requiredUCode[dolphin] ~= 0 THEN loadmap.PutF[" Dolphin: %t\N", IO.time[[data.header.requiredUCode[dolphin]]]]; IF data.header.requiredUCode[dorado] ~= 0 THEN loadmap.PutF[" Dorado: %t\N", IO.time[[data.header.requiredUCode[dorado]]]]; IF data.header.requiredUCode[dandelion] ~= 0 THEN loadmap.PutF[" Dandelion: %t\N", IO.time[[data.header.requiredUCode[dandelion]]]]; IF data.header.requiredUCode[dicentra] ~= 0 THEN loadmap.PutF[" Dicentra: %t\N", IO.time[[data.header.requiredUCode[dicentra]]]]; loadmap.PutF["\N GFT length = %d\N PDA pages = %d\N Processes = %d\N", IO.card[data.gftLength], IO.card[data.pdaPages], IO.card[data.nProcesses]]; loadmap.PutF[" MDS base = page %d [%n]\N Code base = page %d [%n]\N\N", IO.card[data.mdsBase], IO.card[data.mdsBase.LONG*PrincOps.wordsPerPage], IO.card[data.codeBase], IO.card[data.codeBase.LONG*PrincOps.wordsPerPage]]; loadmap.PutF[" Statevector length = %d\N Statevector counts:\N", IO.card[data.svSize]]; FOR i: CARDINAL IN PrincOps.Priority DO loadmap.PutF["%6d: %d\N", IO.card[i], IO.card[data.stateVectorCounts[i]]]; ENDLOOP; loadmap.PutF[ "\N Frame heap pages = %d\N Frame distribution: [ FSI (words): %g, next FSI ]\N", IO.card[data.framePages], IO.rope[IF data.framePages = 0 THEN "count" ELSE "weight"]]; FOR i: PrincOps.FrameSizeIndex IN PrincOps.FrameSizeIndex DO loadmap.PutF[" %3d (%4d): %d, %d\N", IO.card[i], IO.card[PrincOps.FrameVec[i]], IO.card[MB.GetFrameWeight[i]], IO.card[MB.GetFsiChain[i]] ]; ENDLOOP; loadmap.PutF["\N Wart: %g", IO.rope[wartModule]]; IF wartConfig ~= NIL THEN loadmap.PutF[" in configuration %g", IO.rope[wartConfig]]; loadmap.PutChar['\N]; IF stateLists[resident] ~= NIL THEN { loadmap.PutRope["\N Resident:\N"]; EchoList[stateLists[resident]]}; IF stateLists[resDesc] ~= NIL THEN { loadmap.PutRope["\N Resident Descriptor:\N"]; EchoList[stateLists[resDesc]]}; IF stateLists[in] ~= NIL THEN { loadmap.PutRope["\N Initially In:\N"]; EchoList[stateLists[in], TRUE]}; IF noTrapList ~= NIL THEN { loadmap.PutRope["\N No Trap:\N"]; EchoList[noTrapList, TRUE]}; IF controlList ~= NIL THEN { loadmap.PutRope["\N Control:\N"]; EchoList[controlList, TRUE]}; loadmap.PutRope["\N\N"]; }; ParseInput: PROC = { lastSep _ Ascii.NUL; DO ENABLE { IO.EndOfStream => ErrorMsg["Unexpected end of input"]; IO.SyntaxError => ErrorMsg[msg]; }; SELECT GetKeyword[ ! IO.EndOfStream => EXIT] FROM gft => data.gftLength _ GetNumber[low: FIRST[PrincOps.GFTIndex]+1, high: LAST[PrincOps.GFTIndex]+1]; mdsbase => data.mdsBase _ GetNumber[]; codebase => data.codeBase _ GetNumber[]; framePages => data.framePages _ GetNumber[low: 0, high: 255]; pdapages => data.pdaPages _ GetNumber[low: 1, high: 256]; processes => data.nProcesses _ GetNumber[low: FIRST[PrincOps.PsbIndex]+1, high: LAST[PrincOps.PsbIndex]+1]; nSV => { svIndex: CARDINAL = GetNumber[low: FIRST[PrincOps.Priority], high: LAST[PrincOps.Priority]]; count: CARDINAL; GetRequiredSep[comma]; count _ GetNumber[]; data.stateVectorCounts[svIndex] _ IF data.stateVectorCounts[svIndex] = LAST[CARDINAL] THEN count ELSE data.stateVectorCounts[svIndex] + count; }; svSize => data.svSize _ GetNumber[low: SIZE[PrincOps.StateVector]]; frameweight, framecount => { Fsi: TYPE = PrincOps.FrameSizeIndex; frameIndex: Fsi = GetNumber[low: FIRST[Fsi], high: LAST[Fsi]]; sep: Separator; GetRequiredSep[comma]; MB.SetFrameWeight[index: frameIndex, weight: GetNumber[]]; sep _ GetSep[]; SELECT sep FROM semiColon => SaveSep[sep]; comma => MB.SetFsiChain[ index: frameIndex, fsiNext: GetNumber[low: FIRST[Fsi], high: LAST[Fsi]]]; ENDCASE => ErrorMsg[Rope.Cat["Unexpected separator '", Rope.FromChar[separators[sep]], "'"]]; }; version => { sep: Separator; data.header.release.major _ GetNumber[]; GetRequiredSep[dot]; data.header.release.minor _ GetNumber[]; sep _ GetSep[]; SELECT sep FROM dot => data.header.release.patch _ GetNumber[]; semiColon => SaveSep[sep]; ENDCASE => ErrorMsg[Rope.Cat["Unexpected separator '", Rope.FromChar[separators[sep]], "'"]]; }; uCodeDolphin => data.header.requiredUCode[dolphin] _ GetUCodeDate[uCodeDolphin]; uCodeDorado => data.header.requiredUCode[dorado] _ GetUCodeDate[uCodeDorado]; uCodeDandelion => data.header.requiredUCode[dandelion] _ GetUCodeDate[uCodeDandelion]; uCodeDicentra => data.header.requiredUCode[dicentra] _ GetUCodeDate[uCodeDicentra]; wart => { r: ROPE = GetID[]; SELECT GetSep[] FROM semiColon => {wartConfig _ NIL; wartModule _ r; SaveSep[semiColon]}; openBracket => { wartConfig _ r; wartModule _ GetID[]; GetRequiredSep[closeBracket]; }; ENDCASE => SyntaxError[wart]; }; resident => stateLists[resident] _ GetGeneralList[stateLists[resident]]; resDesc => stateLists[resDesc] _ GetGeneralList[stateLists[resDesc]]; in => stateLists[in] _ GetGeneralList[stateLists[in]]; noTrap => noTrapList _ GetModuleList[noTrapList]; control => controlList _ GetNameList[controlList]; ENDCASE; GetRequiredSep[semiColon]; ENDLOOP; }; GetKeyword: PROC RETURNS [key: Keyword] = { id: ROPE = GetID[]; IF GetSep[] ~= colon THEN ErrorMsg[IO.PutFR["No colon following keyword '%g'", IO.rope[id]]]; FOR key IN Keyword DO IF id.Equal[keywords[key]] THEN RETURN ENDLOOP; ErrorMsg[IO.PutFR["Unrecognizable keyword '%g'", IO.rope[id]]]; }; GetRequiredSep: PROC [esep: Separator] = { IF GetSep[] ~= esep THEN ErrorMsg[IO.PutFR["Expected separator '%g' not found", IO.char[separators[esep]]]]; }; GetGeneralList: PROC [oldList: Node _ NIL] RETURNS [list: Node] = { list _ oldList; DO sep: Separator; list _ AppendNode[list, GetListItem[]]; IF (sep _ GetSep[]) ~= comma THEN {SaveSep[sep]; EXIT}; ENDLOOP; }; GetListItem: PROC RETURNS [item: Node] = { r: ROPE = GetID[]; SELECT TRUE FROM r.Equal[keywords[space]], r.Equal[keywords[codepack]] => item _ NEW[Item _ [link: NIL, body: space[list: GetBracketedNameList[]]]]; r.Equal[keywords[frame]], r.Equal[keywords[framepack]] => item _ NEW[Item _ [link: NIL, body: frame[list: GetBracketedNameList[]]]]; r.Equal[keywords[bcd]] => item _ NEW[Item _ [link: NIL, body: bcd[list: GetBracketedNameList[]]]]; r.Equal[keywords[globalFrame]] => item _ NEW[Item _ [link: NIL, body: globalframe[list: GetBracketedConfigPartList[]]]]; r.Equal[keywords[code]] => item _ NEW[Item _ [link: NIL, body: code[list: GetBracketedConfigPartList[]]]]; ENDCASE => item _ GetConfigPart[r]; }; GetBracketedConfigPartList: PROC RETURNS [list: Node] = { GetRequiredSep[openBracket]; list _ GetConfigPartList[]; GetRequiredSep[closeBracket]; }; GetConfigPartList: PROC RETURNS [list: Node] = { list _ NIL; DO sep: Separator; list _ AppendNode[list, GetConfigPart[GetID[]]]; IF (sep _ GetSep[]) ~= comma THEN {SaveSep[sep]; EXIT}; ENDLOOP; }; GetConfigPart: PROC [r: ROPE] RETURNS [item: Node] = { sep: Separator = GetSep[]; IF sep = openBracket THEN { item _ NEW[Item _ [link: NIL, body: config[name: r, list: GetModuleList[]]]]; GetRequiredSep[closeBracket]; } ELSE {SaveSep[sep]; item _ GetModule[first: r]}; }; GetModuleList: PROC [oldList: Node _ NIL] RETURNS [list: Node] = { list _ oldList; DO sep: Separator; list _ AppendNode[list, GetModule[]]; IF (sep _ GetSep[]) ~= comma THEN {SaveSep[sep]; EXIT}; ENDLOOP; }; GetModule: PROC [first: ROPE _ NIL] RETURNS [node: Node] = { sep: Separator; IF first = NIL THEN first _ GetID[]; IF (sep _ GetSep[]) = dot THEN node _ NEW[Item _ [link: NIL, body: dot[module: first, instance: GetID[]]]] ELSE { SaveSep[sep]; node _ NEW[Item _ [link: NIL, body: name[name: first]]]; }; }; GetBracketedNameList: PROC RETURNS [list: Node] = { GetRequiredSep[openBracket]; list _ GetNameList[]; GetRequiredSep[closeBracket]; }; GetNameList: PROC [oldList: Node _ NIL] RETURNS [list: Node] = { list _ oldList; DO sep: Separator; list _ AppendNode[list, GetName[]]; IF (sep _ GetSep[]) ~= comma THEN {SaveSep[sep]; EXIT}; ENDLOOP; }; GetName: PROC RETURNS [Node] = { RETURN[NEW[Item _ [link: NIL, body: name[name: GetID[]]]]]}; AppendNode: PROC [list: Node, node: Node] RETURNS [newList: Node] = { IF list = NIL THEN node.link _ node ELSE {node.link _ list.link; list.link _ node}; RETURN[node] }; GetID: PROC RETURNS [ROPE] = { RETURN[source.GetId[]] }; GetNumber: PROC [ low: CARDINAL _ FIRST[CARDINAL], high: CARDINAL _ LAST[CARDINAL]] RETURNS [CARDINAL] = { GetCard: PROC [stream: IO.STREAM] RETURNS [LONG CARDINAL] = { initial: BOOL _ TRUE; Digit: IO.CharProc = TRUSTED { SELECT char FROM IN ['0..'9] => {initial _ FALSE; RETURN[quit: FALSE, include: TRUE]}; IN ['A..'Z], IN ['a..'z] => RETURN[quit: TRUE, include: ~initial]; Ascii.SP, Ascii.TAB, Ascii.CR => RETURN[quit: ~initial, include: FALSE]; ENDCASE => RETURN[quit: TRUE, include: FALSE]; }; RETURN[IO.GetCard[IO.RIS[source.GetSequence[Digit]]]] }; number: LONG CARDINAL = --source.GetCard[]-- GetCard[source]; IF ~(number IN [low..high]) THEN ErrorMsg[IO.PutFR["'%d' is out of range", IO.card[number]]]; RETURN [number] }; GetSep: PROC RETURNS [sep: Separator] = { char: CHAR; IF lastSep ~= Ascii.NUL THEN {char _ lastSep; lastSep _ Ascii.NUL} ELSE { source.SkipOver[]; -- skip white space char _ source.GetChar[]; }; FOR sep IN Separator DO IF char = separators[sep] THEN EXIT; REPEAT FINISHED => ErrorMsg[IO.PutFR["Illegal character '%g'", IO.char[char]]]; ENDLOOP; }; SaveSep: PROC [sep: Separator] = { IF lastSep ~= Ascii.NUL THEN ERROR; lastSep _ separators[sep]; }; GetUCodeDate: PROC [key: Keyword] RETURNS [date: SystemVersion.Date] = { r: ROPE _ NIL; basicTime: BasicTime.GMT; notes: DateAndTime.Notes; DO char: CHAR = source.GetChar[ ! IO.EndOfStream => ErrorMsg[IO.PutFR["Missing ';' for '%g'", IO.rope[keywords[key]]]] ]; IF char = '; THEN EXIT; r _ r.Concat[Rope.FromChar[char]]; ENDLOOP; [dt: basicTime, notes: notes] _ DateAndTime.Parse[r ! DateAndTime.Unintelligible => ErrorMsg[IO.PutFR["Illegal date for '%g'", IO.rope[keywords[key]]]] ]; IF notes ~= normal THEN ErrorMsg[IO.PutFR["Incomplete date specification for '%g'", IO.rope[keywords[key]]]]; SaveSep[semiColon]; RETURN[--BasicTime.ToPupTime[basicTime]--LOOPHOLE[basicTime]] }; SyntaxError: PROC [key: Keyword] = { ErrorMsg[IO.PutFR["Bad specification for '%g'", IO.rope[keywords[key]]]]; }; ErrorMsg: PROC [msg: ROPE] = { data.typescript.PutF["\N! Syntax Error [%d]: %g\N", IO.card[source.GetIndex], IO.rope[msg]]; ERROR MB.Abort }; WartFrame: PUBLIC PROC RETURNS [g: PrincOps.GlobalFrameHandle] = { IF wartConfig ~= NIL THEN MB.SetConfig[wartConfig]; g _ MB.NameToG[wartModule]; MB.ResetConfig[]; }; EnumerateCode: PUBLIC PROC [ state: ListType, proc: PROC [bh: BHandle, mth: BcdDefs.MTHandle] RETURNS [BOOL]] = { PackageableOnly: PROC [bh: BHandle, mth: BcdDefs.MTHandle] RETURNS [BOOL] = { RETURN[IF mth.packageable THEN proc[bh, mth] ELSE FALSE]}; [] _ DoModules[stateLists[state], PackageableOnly]; }; EnumerateGlobalFrames: PUBLIC PROC [ state: ListType, proc: PROC [bh: BHandle, mth: BcdDefs.MTHandle] RETURNS [BOOL]] = { PackageableOnly: PROC [bh: BHandle, mth: BcdDefs.MTHandle] RETURNS [BOOL] = { RETURN[IF mth.packageable THEN proc[bh, mth] ELSE FALSE]}; p: Node _ stateLists[state]; IF p ~= NIL THEN DO p _ p.link; WITH p SELECT FROM globalframe => IF DoModules[list, PackageableOnly] THEN EXIT; ENDCASE; IF p = stateLists[state] THEN EXIT; ENDLOOP; }; EnumerateFramePacks: PUBLIC PROC [ state: ListType, proc: PROC [bh: BHandle, fph: BcdDefs.FPHandle] RETURNS [BOOL]] = { p: Node _ stateLists[state]; IF p ~= NIL THEN DO p _ p.link; WITH p SELECT FROM frame => { PassItOn: PROC [name: ROPE] RETURNS [BOOL] = { bh: BHandle; fph: BcdDefs.FPHandle; IF Rope.Equal[name, "ALL", TRUE] THEN { [] _ DoAllFramePacks[proc]; RETURN[TRUE] }; [bh: bh, fph: fph] _ NameToFPHandle[name]; RETURN[proc[bh, fph]] }; IF DoNames[list, PassItOn] THEN EXIT; }; ENDCASE; IF p = stateLists[state] THEN EXIT; ENDLOOP; }; EnumerateSpaces: PUBLIC PROC [ state: ListType, proc: PROC [bh: BHandle, sph: BcdDefs.SPHandle, index: CARDINAL] RETURNS [BOOL]] = { p: Node _ stateLists[state]; IF p ~= NIL THEN DO p _ p.link; WITH p SELECT FROM space => { PassItOn: PROC [name: ROPE] RETURNS [BOOL] = { bh: BHandle; sph: BcdDefs.SPHandle; index: CARDINAL; IF Rope.Equal[name, "ALL", TRUE] THEN { [] _ DoAllSpaces[proc]; RETURN[TRUE] }; [bh: bh, sph: sph, index: index] _ NameToSPHandle[name]; RETURN[proc[bh, sph, index]] }; IF DoNames[list, PassItOn] THEN EXIT; }; ENDCASE; IF p = stateLists[state] THEN EXIT; ENDLOOP; }; EnumerateBCDs: PUBLIC PROC [state: ListType, proc: PROC [bh: BHandle] RETURNS [BOOL]] = { p: Node _ stateLists[state]; IF p ~= NIL THEN DO p _ p.link; WITH p SELECT FROM bcd => { PassItOn: PROC [name: ROPE] RETURNS [BOOL] = { IF Rope.Equal[name, "ALL", TRUE] THEN { [] _ DoAllBCDs[proc]; RETURN[TRUE] }; RETURN[proc[NameToCTHandle[name].bh]] }; IF DoNames[list, PassItOn] THEN EXIT; }; ENDCASE; IF p = stateLists[state] THEN EXIT; ENDLOOP; }; EnumerateNoTrapModules: PUBLIC PROC [ proc: PROC [bh: BHandle, mth: BcdDefs.MTHandle] RETURNS [BOOL]] = { [] _ DoModules[noTrapList, proc]; }; EnumerateControlList: PUBLIC PROC [ proc: PROC [bh: BHandle, cth: BcdDefs.CTHandle] RETURNS [BOOL]] = { PassItOn: PROC [name: ROPE] RETURNS [BOOL] = { bh: MB.BHandle; cth: BcdDefs.CTHandle; IF Rope.Equal[name, "ALL", TRUE] THEN { [] _ DoAllTopLevelConfigs[proc]; RETURN[TRUE] }; [bh, cth] _ NameToCTHandle[name]; RETURN[proc[bh, cth]] }; [] _ DoNames[controlList, PassItOn]; }; DoModules: PROC [ tail: Node, proc: PROC [bh: BHandle, mth: BcdDefs.MTHandle] RETURNS [BOOL]] RETURNS [stopped: BOOL] = { p: Node _ tail; stopped _ TRUE; IF p = NIL THEN RETURN[FALSE]; DO bh: MB.BHandle; mth: BcdDefs.MTHandle; p _ p.link; WITH p SELECT FROM name => IF name.Equal[keywords[all]] THEN { IF MB.DoAllModules[proc] THEN RETURN} ELSE { [bh: bh, mth: mth] _ NameToMTHandle[name]; IF bh ~= NIL AND proc[bh, mth] THEN RETURN; }; dot => { [bh: bh, mth: mth] _ InstanceToMTHandle[module: module, instance: instance]; IF bh ~= NIL AND proc[bh, mth] THEN RETURN; }; config => { done: BOOL; MB.SetConfig[name]; done _ DoModules[list, proc]; MB.ResetConfig[]; IF done THEN RETURN; }; code => IF DoModules[list, proc] THEN RETURN; ENDCASE; -- skip over space, frame, globalframe, bcd IF p = tail THEN EXIT; ENDLOOP; RETURN[FALSE] }; DoNames: PROC [tail: Node, proc: PROC [name: ROPE] RETURNS [BOOL]] RETURNS [BOOL] = { p: Node _ tail; IF p ~= NIL THEN DO p _ p.link; WITH p SELECT FROM name => IF proc[name] THEN RETURN[TRUE]; ENDCASE => ERROR; IF p = tail THEN EXIT; ENDLOOP; RETURN[FALSE] }; END. LMBParse.mesa Edited by Sandman on 6-Aug-81 15:42:09 Edited by Lewis on 18-Sep-81 15:00:15 Edited by Levin on June 22, 1983 10:45 am Syntax for RESIDENT, RESIDENTDESCRIPTOR, IN, NOTRAP, and CONTROL: Resident ::= RESIDENT : list ; ResidentDescriptor ::= RESIDENTDESCRIPTOR : list ; In ::= IN : list ; NoTrap ::= NOTRAP : moduleList ; Control ::= CONTROL : nameList ; list ::= listItem | list , listItem listItem ::= configPart | CODE [ configPartList ] GLOBALFRAME [ configPartList ] SPACE [ nameList ] | CODEPACK [ nameList ] | FRAME [ nameList ] | FRAMEPACK [ nameList ] | BCD [ nameList ] | configPartList ::= configPart | configPartList , configPart configPart ::= module | configName [ moduleList ] moduleList ::= module | moduleList , module module ::= name | name . instance nameList ::= name | nameList , name Bootmesa file parsing This procedure exists solely to ensure that the lists are garbage-collected promptly. put at end of list for printing by EchoInput Use this until (if ever) the real one does what we want (terminates on any punctuation, including "."). Even this requires programming around some infelicities of IO. Bootmesa file interrogation The syntax equations ensure that we will not recur under the following call of DoModules. This is important since SetConfig and ResetConfig do not follow a stack discipline. �ÊÓ˜Jšœ™Jšœ&™&Jšœ%™%Jšœ)™)J˜šÏk ˜ Jš œ�œ�œ�œ�œ�œ˜Jšœ �œ�Ïcœ˜%Jšœ�œ*˜7Jšœ�œ˜!Jšœ �œ ˜1Jšœ�œ˜š�œ�œ˜ Jšœ•�œ�œ˜Å—š�œ�œ˜ J˜¥—šœ �œ˜Jšœf˜f—Jšœ�œ �œ˜0Jšœ �œ3˜AJšœ�œ˜Jšœ�œ ˜J˜—šœ �˜Jš�œžœ$�œ�œ˜QJš�œ�œ˜ —J˜Jš�˜J˜Jš�œ�œ˜J˜JšœA™AItable1šœ™Kšœ2™2Kšœ™Kšœ ™ Kšœ ™ Kšœ#™#Kšœ1™1Kšœ ™ Kšœ.™.Kšœ/™/Kšœ™Kšœ;™;Kšœ1™1Kšœ+™+Kšœ!™!Kšœ#™#J˜J˜Jš�œ�œ�œ˜J˜Jšœ�œ �œ˜Jšœ�œ�œ�œ˜J˜J˜J˜Jšœ �œ �œž0˜UJšœ�œ˜J˜Jšœ�œ�œ˜šœ�œ�œ˜J˜ šœ�œ �˜Jšœ�œ˜Jšœ�œ˜ Jšœ�œ˜#J˜J˜J˜J˜J˜Jš�˜—šœ˜J˜——Jšœ �œ=˜Lšœ �œ˜J˜�J˜—šœ �œ �œ�œ˜#J˜ë—J˜Jšœ �œ �œ�œ˜?J˜Jšœ � œ˜J˜Jšœ �œ�œ˜$šœ�œ�œ˜Jšœ�œ˜Jšœ�œ˜ J˜J˜—Jšœ�œž0˜NJ˜Jšœ™J˜šÏn œ�œ�œ�œ ˜)J˜ Jšœ˜Jšœ˜J˜—šŸ œ�œ�œ˜šŸœ�œ˜JšœU™UšŸ œ�œ˜!J˜Jš�œ�œ�œ�œ˜š�˜J˜ š�œ�œ�˜Jšœ�œ˜ Jšœ�œ˜ Jšœ˜Jšœ˜Jšœ˜Jšœ"˜"Jšœ˜Jšœ˜Jš�œ˜—Jš�œ �œ�œ˜Jš�œ˜—Jšœ �œ˜Jšœ˜—Jš�œ�œ�œ�œ˜0š�œ�œ �˜!J˜Jš�œ˜—J˜J˜J˜—J˜Jšœ˜Jšœ�œ˜ Jšœ˜J˜—šŸ œ�œ˜Jšœ �œ˜Jšœ�œ˜Jšœ �œ�œ˜Jšœ�œ˜Jšœ �œ˜ Jšœ �œ˜Jšœ˜J˜—šŸ œ�œ�œ�œ˜*Jšœ�œ˜J˜Jšœ�œ˜9J˜0šœ˜JšœD˜D—Jšœ4˜4Jšœ �œ/˜:J˜ Jšœž,˜=Jšœ,™,Jš�œ�œ�œ˜3Jš�œA˜EJ˜J˜J˜—šŸ œ�œ�œ˜Jšœ �œ�œ˜"šŸœ�œ�œ�œ˜6J˜Jš�œ �œ�œ˜Bš�œ�œ�˜š�˜J˜ š�œ�œ�˜Jšœ˜Jšœ�œ�œ˜AJšœ1�œ˜9Jšœ>�œ˜FJšœ?�œ˜GJšœG�œ˜OJšœ9�œ˜AJšœ7�œ˜?Jš�œ˜—Jš�œ �œ�œ˜Jšœ�œ �œ �œ˜6Jš�œ˜——Jš�œ �œ˜'Jš�œ˜Jšœ˜—š�œ�œ�œ˜J˜'šœ%˜%Jš �œ�œ�œ�œ�œ˜7—š�˜Jšœ�œ�œ˜QJš�œ�œ�œ˜$J˜Jš�œ˜—Jšœ˜Jšœ˜—Jšœ)˜)˜%Jš�œ"�œ!˜Gš�œ˜Jš�œ�œ�˜)Jš�œ�œ�œ"˜9—Jšœ˜—J˜6š�œ)�˜/Jšœ#�œ-˜R—š�œ(�˜.Jšœ"�œ,˜P—š�œ+�˜1Jšœ%�œ/˜V—š�œ*�˜0Jšœ$�œ.˜T—šœI˜IJš�œ�œ�œ˜K—šœI˜IJš�œ�œ�œ˜HJš�œ�œ�œ˜K—JšœC�œ˜Yš�œ�œ�œ�˜'Jšœ�œ �œ"˜KJš�œ˜—šœ ˜ JšœT˜TJš �œ�œ�œ�œ �œ ˜V—š�œ�œ�˜<šœ&˜&Jš�œ ˜ Jš�œ˜Jš�œ�œ˜Jš�œ�œ˜J˜—Jš�œ˜—Jšœ�œ˜2Jš�œ�œ�œ&�œ˜TJšœ˜š�œ�œ�œ˜%JšœD˜D—š�œ�œ�œ˜$JšœN˜N—š�œ�œ�œ˜JšœA�œ˜H—š�œ�œ�œ˜Jšœ8�œ˜?—š�œ�œ�œ˜Jšœ9�œ˜@—Jšœ˜Jšœ˜J˜—šŸ œ�œ˜Jšœ�œ˜š�˜š�œ˜Jš�œ4˜6Jš�œ˜ J˜—š�œ�œ�œ�˜1˜˜Jšœ�œ�œ˜L——Jšœ&˜&Jšœ(˜(Jšœ=˜=Jšœ9˜9˜ šœ˜Jšœ�œ�œ˜L——˜šœ �œ˜Jšœ�œ�œ˜H—Jšœ�œ˜J˜J˜˜!Jš�œ#�œ�œ�œ˜>Jš�œ)˜-—J˜—Jšœ'�œ˜C˜Jšœ�œ˜$Jšœ!�œ �œ˜>J˜J˜Jš�œ8˜:J˜š�œ�˜Jšœ˜˜š�œ ˜Jšœ+�œ �œ˜I——š�œ˜ JšœR˜R——Jšœ˜—˜ J˜Jšœ(˜(J˜Jšœ(˜(J˜š�œ�˜Jšœ/˜/J˜š�œ˜ JšœR˜R——J˜—˜J˜@—˜J˜>—˜J˜D—˜J˜B—˜ Jšœ�œ ˜š�œ �˜Jšœ�œ&˜D˜Jšœ˜J˜J˜J˜—Jš�œ˜—Jšœ˜—J˜HJ˜EJ˜6J˜1J˜2Jš�œ˜—J˜Jš�œ˜—šœ˜J˜——šŸ œ�œ�œ˜+Jšœ�œ ˜Jš�œ�œ �œ*�œ ˜]Jš�œ�œ �œ�œ�œ�œ�œ˜EJšœ �œ&�œ ˜?J˜J˜—šŸœ�œ˜*š�œ�˜Jšœ �œ,�œ˜S—Jšœ˜J˜—šŸœ�œ�œ�œ˜CJ˜š�˜J˜J˜'Jš�œ�œ�œ˜7Jš�œ˜—šœ˜J˜——šŸ œ�œ�œ˜*Jšœ�œ ˜š�œ�œ�˜˜8Jšœ�œ�œ.˜J—˜9Jšœ�œ�œ.˜J—˜Jšœ�œ�œ,˜H—˜!Jšœ�œ�œ:˜V—˜Jšœ�œ�œ3˜O—Jš�œ˜#—šœ˜J˜——šŸœ�œ�œ˜9J˜J˜J˜J˜J˜—šŸœ�œ�œ˜0Jšœ�œ˜ š�˜J˜Jšœ0˜0Jš�œ�œ�œ˜7Jš�œ˜—šœ˜J˜——šŸ œ�œ�œ�œ˜6J˜š�œ�œ˜Jšœ�œ�œ1˜MJ˜J˜—Jš�œ,˜0Jšœ˜J˜—šŸ œ�œ�œ�œ˜BJ˜š�˜J˜J˜%Jš�œ�œ�œ˜7Jš�œ˜—Jšœ˜J˜—š Ÿ œ�œ �œ�œ�œ˜