MBUtilities.mesa
Edited by Sandman on 6-Aug-81 15:47:39
Edited by Lewis on 17-Sep-81 15:51:36
Edited by Levin on May 24, 1983 10:21 am
DIRECTORY
Ascii USING [CR],
BcdDefs USING [
Base, BcdBase, CTHandle, CTIndex, CTNull, CTRecord, FPHandle, FPIndex, FTSelf, MTHandle, MTIndex, NameString, NTHandle, NTIndex, SPHandle, SPIndex],
BcdOps USING [
ProcessConfigs, ProcessFramePacks, ProcessModules, ProcessNames, ProcessSpaces],
IO USING [PutChar, PutF, PutRope, rope, STREAM],
MB USING [Abort, BHandle, BIndex, Handle],
MBVM USING [CopyRead],
PrincOps USING [GlobalFrame, GlobalFrameHandle],
Rope USING [Equal, FromProc, ROPE];
MBUtilities: PROGRAM
IMPORTS BcdOps, IO, MB, MBVM, Rope
EXPORTS MB =
BEGIN
data: MB.Handle ← NIL;
currentBH: MB.BHandle;
currentCti: BcdDefs.CTIndex;
currentConfig: Rope.ROPE;
InitUtilities: PUBLIC PROC [h: MB.Handle] = {
data ← h;
ResetConfig[];
currentFrame ← NIL;
};
FinishUtilities: PUBLIC PROC = {
ResetConfig[];
data ← NIL;
};
NameToG: PUBLIC PROC [name: Rope.ROPE] RETURNS [PrincOps.GlobalFrameHandle] = {
bh: MB.BHandle;
mth: BcdDefs.MTHandle;
[bh, mth] ← NameToMTHandle[name];
RETURN[IF mth ~= NIL THEN bh.mt[mth.gfi].frame ELSE NIL]
};
NameToMTHandle: PUBLIC PROC [name: Rope.ROPE]
RETURNS [bh: MB.BHandle, mth: BcdDefs.MTHandle] = {
nmth: BcdDefs.MTHandle ← NIL;
DoOneBCD: PROC [thisBH: MB.BHandle] RETURNS [BOOL] = {
bcd: BcdDefs.BcdBase = thisBH.bcd;
ssb: BcdDefs.NameString = LOOPHOLE[bcd + bcd.ssOffset];
CheckModule: PROC [mth: BcdDefs.MTHandle, mti: BcdDefs.MTIndex]
RETURNS [BOOL] = {
i: INT ← mth.name;
Proc: SAFE PROC RETURNS [char: CHARACTER] = TRUSTED {
char ← ssb.string[i]; i ← i + 1};
IF currentCti ~= BcdDefs.CTNull AND
(currentBH ~= thisBH OR mth.config ~= currentCti) THEN RETURN[FALSE];
IF mth.namedInstance THEN RETURN[FALSE];
IF Rope.Equal[s1: name, s2: Rope.FromProc[ssb.size[mth.name], Proc], case: TRUE] THEN
IF nmth = NIL THEN {bh ← thisBH; nmth ← mth}
ELSE AmbiguousName[name: name];
RETURN[FALSE]
};
[] ← BcdOps.ProcessModules[bcd, CheckModule];
RETURN[FALSE]
};
[] ← DoAllBCDs[DoOneBCD];
IF (mth ← nmth) ~= NIL THEN RETURN;
SearchError[thing: "module", s1: name];
RETURN[NIL, NIL]
};
AmbiguousName: PROC [name: Rope.ROPE] = {
typescript: IO.STREAM = data.typescript;
typescript.PutRope["\N! Ambiguous name"];
IF currentConfig ~= NIL THEN
typescript.PutF["%g[%g]\N", IO.rope[currentConfig], IO.rope[name]]
ELSE typescript.PutF["%g\N", IO.rope[name]];
SIGNAL MB.Abort;
};
SearchError: PROC [thing: Rope.ROPE, s1: Rope.ROPE, s2: Rope.ROPENIL] = {
typescript: IO.STREAM = data.typescript;
don't give error message if not all BCDs have been loaded.
IF data.inputBCDs.bcds[data.inputBCDs.nBcds-1].bcd = NIL THEN RETURN;
typescript.PutF["\N! Can't find %g ", IO.rope[thing]];
IF currentConfig ~= NIL THEN {typescript.PutF["%g[", IO.rope[currentConfig]]};
typescript.PutRope[s1]; IF s2 ~= NIL THEN typescript.PutF[".%g", IO.rope[s2]];
IF currentConfig ~= NIL THEN typescript.PutChar[']];
typescript.PutChar[Ascii.CR];
SIGNAL MB.Abort;
};
NameToFPHandle: PUBLIC PROC [name: Rope.ROPE]
RETURNS [bh: MB.BHandle, fph: BcdDefs.FPHandle] = {
DoOneBCD: PROC [thisBH: MB.BHandle] RETURNS [BOOL] = {
bcd: BcdDefs.BcdBase = (bh ← thisBH).bcd;
ssb: BcdDefs.NameString = LOOPHOLE[bcd + bcd.ssOffset];
CheckFramePack: PROC [fph: BcdDefs.FPHandle, fpi: BcdDefs.FPIndex] RETURNS [BOOL] = {
i: INT ← fph.name;
Proc: SAFE PROC RETURNS [char: CHARACTER] = TRUSTED {
char ← ssb.string[i]; i ← i + 1};
RETURN[Rope.Equal[s1: name, s2: Rope.FromProc[ssb.size[fph.name], Proc], case: TRUE]]
};
RETURN[(fph ← BcdOps.ProcessFramePacks[bcd, CheckFramePack].fph) ~= NIL]
};
IF DoAllBCDs[DoOneBCD] THEN RETURN;
SearchError[thing: "frame pack", s1: name];
RETURN[NIL, NIL]
};
NameToSPHandle: PUBLIC PROC [name: Rope.ROPE]
RETURNS [bh: MB.BHandle, sph: BcdDefs.SPHandle, index: CARDINAL] = {
DoOneBCD: PROC [thisBH: MB.BHandle] RETURNS [BOOL] = {
bcd: BcdDefs.BcdBase = (bh ← thisBH).bcd;
ssb: BcdDefs.NameString = LOOPHOLE[bcd + bcd.ssOffset];
CheckSpace: PROC [sph: BcdDefs.SPHandle, spi: BcdDefs.SPIndex] RETURNS [BOOL] = {
FOR i: CARDINAL IN [0..sph.length) DO
j: INT ← sph.spaces[i].name;
Proc: SAFE PROC RETURNS [char: CHARACTER] = TRUSTED {
char ← ssb.string[j]; j ← j + 1};
IF Rope.Equal[s1: name, s2: Rope.FromProc[ssb.size[sph.spaces[i].name], Proc], case: TRUE] THEN {index ← i; RETURN[TRUE]};
ENDLOOP;
RETURN[FALSE]
};
RETURN[(sph ← BcdOps.ProcessSpaces[bcd, CheckSpace].sph) ~= NIL]
};
IF DoAllBCDs[DoOneBCD] THEN RETURN;
SearchError[thing: "code pack", s1: name];
RETURN[NIL, NIL, 0]
};
fakeCTRecord: ARRAY [0..SIZE[BcdDefs.CTRecord]+1) OF WORD;
NameToCTHandle: PUBLIC PROC [name: Rope.ROPE]
RETURNS [bh: MB.BHandle, cth: BcdDefs.CTHandle] = {
DoOneBCD: PROC [thisBH: MB.BHandle] RETURNS [found: BOOL] = {
bcd: BcdDefs.BcdBase = (bh ← thisBH).bcd;
ssb: BcdDefs.NameString = LOOPHOLE[bcd + bcd.ssOffset];
i: INT;
Proc: SAFE PROC RETURNS [char: CHARACTER] = TRUSTED {char ← ssb.string[i]; i ← i + 1};
CheckConfig: PROC [cth: BcdDefs.CTHandle, cti: BcdDefs.CTIndex] RETURNS [BOOL] = {
i ← cth.name;
RETURN[Rope.Equal[s1: name, s2: Rope.FromProc[ssb.size[cth.name], Proc], case: TRUE]]
};
IF bcd.nConfigs = 0 THEN {
assert: bcd.nModules = 1
mth: BcdDefs.MTHandle = LOOPHOLE[bcd + bcd.mtOffset];
i ← mth.name;
IF (found ← Rope.Equal[s1: name, s2: Rope.FromProc[ssb.size[mth.name], Proc], case: TRUE]) THEN {
cth ← LOOPHOLE[LONG[@fakeCTRecord]];
cth^ ← [
name: mth.name,
namedInstance: FALSE,
file: BcdDefs.FTSelf,
config: BcdDefs.CTNull,
nControls: 1,
controls:
];
cth.controls[0] ← [module[mti: LOOPHOLE[0]]];
};
}
ELSE RETURN[(cth ← BcdOps.ProcessConfigs[bcd, CheckConfig].cth) ~= NIL]
};
cth ← NIL;
IF DoAllBCDs[DoOneBCD] THEN RETURN;
SearchError[thing: "configuration", s1: name];
RETURN[NIL, NIL]
};
InstanceToMTHandle: PUBLIC PROC [module, instance: Rope.ROPE]
RETURNS [bh: MB.BHandle, mth: BcdDefs.MTHandle] = {
DoOneBCD: PROC [thisBH: MB.BHandle] RETURNS [BOOL] = {
bcd: BcdDefs.BcdBase = (bh ← thisBH).bcd;
mtb: BcdDefs.Base = LOOPHOLE[bcd + bcd.mtOffset];
ssb: BcdDefs.NameString = LOOPHOLE[bcd + bcd.ssOffset];
CheckName: PROC [nth: BcdDefs.NTHandle, nti: BcdDefs.NTIndex] RETURNS [BOOL] = {
WITH nth.item SELECT FROM
module => {
i: INT ← nth.name;
Proc: SAFE PROC RETURNS [char: CHARACTER] = TRUSTED {
char ← ssb.string[i]; i ← i + 1};
IF Rope.Equal[s1: instance, s2: Rope.FromProc[ssb.size[nth.name], Proc], case: TRUE] THEN {
IF currentCti ~= BcdDefs.CTNull AND
(currentBH ~= bh OR mtb[mti].config ~= currentCti) THEN RETURN[FALSE];
i ← mtb[mti].name;
IF Rope.Equal[s1: module, s2: Rope.FromProc[ssb.size[mtb[mti].name], Proc], case: TRUE] THEN {
mth ← @mtb[mti];
RETURN[TRUE]
};
};
};
ENDCASE => RETURN[FALSE];
RETURN[FALSE]};
RETURN[BcdOps.ProcessNames[bcd, CheckName].nth ~= NIL]
};
mth ← NIL;
IF DoAllBCDs[DoOneBCD] THEN RETURN;
SearchError[thing: "module instance", s1: instance, s2: module];
RETURN[NIL, NIL]
};
DoAllModules: PUBLIC PROC [proc: PROC [MB.BHandle, BcdDefs.MTHandle] RETURNS [BOOL]]
RETURNS [BOOL] = {
IF currentCti = BcdDefs.CTNull THEN {
do all modules in all loaded BCDs
DoOneBCD: PROC [bh: MB.BHandle] RETURNS [BOOL] = {
PassItOn: PROC [mth: BcdDefs.MTHandle, mti: BcdDefs.MTIndex] RETURNS [BOOL] = {
RETURN[proc[bh, mth]]};
RETURN[BcdOps.ProcessModules[bh.bcd, PassItOn].mth ~= NIL]
};
RETURN[DoAllBCDs[DoOneBCD]]
}
ELSE {
do only modules within <currentBH.bcd, currentCti>, including subconfigurations
bcd: BcdDefs.BcdBase = currentBH.bcd;
ctb: BcdDefs.Base = LOOPHOLE[bcd + bcd.ctOffset];
DoOneModule: PROC [mth: BcdDefs.MTHandle, mti: BcdDefs.MTIndex] RETURNS [BOOL] = {
FOR cti: BcdDefs.CTIndex ← mth.config, ctb[cti].config UNTIL cti = BcdDefs.CTNull DO
IF cti = currentCti AND proc[currentBH, mth] THEN RETURN[TRUE];
ENDLOOP;
RETURN[FALSE]
};
RETURN[BcdOps.ProcessModules[bcd, DoOneModule].mth ~= NIL]
};
};
DoAllBCDs: PUBLIC PROC [proc: PROC [MB.BHandle] RETURNS [BOOL]] RETURNS [BOOL] = {
FOR i: MB.BIndex IN [0..data.inputBCDs.nBcds) DO
bh: MB.BHandle = data.inputBCDs.bcds[i];
IF bh.bcd ~= NIL AND proc[bh] THEN RETURN[TRUE];
ENDLOOP;
RETURN[FALSE]
};
DoAllSpaces: PUBLIC PROC [
proc: PROC [MB.BHandle, BcdDefs.SPHandle, CARDINAL] RETURNS [BOOL]]
RETURNS [BOOL] = {
DoOneBCD: PROC [bh: MB.BHandle] RETURNS [BOOL] = {
PassItOn: PROC [sph: BcdDefs.SPHandle, spi: BcdDefs.SPIndex]
RETURNS [BOOL] = {
FOR i: CARDINAL IN [0..sph.length) DO
IF proc[bh, sph, i] THEN RETURN[TRUE];
ENDLOOP;
RETURN[FALSE]
};
RETURN[BcdOps.ProcessSpaces[bh.bcd, PassItOn].sph ~= NIL]
};
RETURN[DoAllBCDs[DoOneBCD]]
};
DoAllFramePacks: PUBLIC PROC [
proc: PROC [MB.BHandle, BcdDefs.FPHandle] RETURNS [BOOL]]
RETURNS [BOOL] = {
DoOneBCD: PROC [bh: MB.BHandle] RETURNS [BOOL] = {
PassItOn: PROC [fph: BcdDefs.FPHandle, fpi: BcdDefs.FPIndex] RETURNS [BOOL] = {
RETURN[proc[bh, fph]]
};
RETURN[BcdOps.ProcessFramePacks[bh.bcd, PassItOn].fph ~= NIL]
};
RETURN[DoAllBCDs[DoOneBCD]]
};
DoAllTopLevelConfigs: PUBLIC PROC [
proc: PROC [MB.BHandle, BcdDefs.CTHandle] RETURNS [BOOL]] RETURNS [BOOL] = {
DoOneBCD: PROC [bh: MB.BHandle] RETURNS [BOOL] = {
bcd: BcdDefs.BcdBase = bh.bcd;
cth: BcdDefs.CTHandle;
FindTopLevel: PROC [cth: BcdDefs.CTHandle, cti: BcdDefs.CTIndex] RETURNS [BOOL] = {
RETURN[cth.config = BcdDefs.CTNull]
};
IF bcd.nConfigs = 0 THEN {
mth: BcdDefs.MTHandle = LOOPHOLE[bcd + bcd.mtOffset];
cth ← LOOPHOLE[LONG[@fakeCTRecord]];
cth^ ← [
name: mth.name,
namedInstance: FALSE,
file: BcdDefs.FTSelf,
config: BcdDefs.CTNull,
nControls: 1,
controls:
];
cth.controls[0] ← [module[mti: LOOPHOLE[0]]];
}
ELSE cth ← BcdOps.ProcessConfigs[bcd, FindTopLevel].cth;
RETURN[proc[bh, cth]]
};
RETURN[DoAllBCDs[DoOneBCD]]
};
SetConfig: PUBLIC PROC [name: Rope.ROPE] = {
DoOneBCD: PROC [bh: MB.BHandle] RETURNS [BOOL] = {
bcd: BcdDefs.BcdBase = bh.bcd;
ssb: BcdDefs.NameString = LOOPHOLE[bcd + bcd.ssOffset];
cti: BcdDefs.CTIndex;
CheckConfig: PROC [cth: BcdDefs.CTHandle, cti: BcdDefs.CTIndex] RETURNS [BOOL] = {
i: INT ← cth.name;
Proc: SAFE PROC RETURNS [char: CHARACTER] = TRUSTED {
char ← ssb.string[i]; i ← i + 1};
RETURN[Rope.Equal[s1: name, s2: Rope.FromProc[ssb.size[cth.name], Proc], case: TRUE]]
};
IF (cti ← BcdOps.ProcessConfigs[bcd, CheckConfig].cti) ~= BcdDefs.CTNull THEN {
currentBH ← bh;
currentCti ← cti;
currentConfig ← name;
RETURN[TRUE]
};
RETURN[FALSE]
};
[] ← DoAllBCDs[DoOneBCD]
};
ResetConfig: PUBLIC PROC = {
currentBH ← NIL;
currentCti ← BcdDefs.CTNull;
currentConfig ← NIL;
};
globalFrame: PrincOps.GlobalFrame;
currentFrame: PrincOps.GlobalFrameHandle;
VirtualGlobalFrame: PUBLIC PROC [f: PrincOps.GlobalFrameHandle]
RETURNS [PrincOps.GlobalFrameHandle] = {
IF f ~= currentFrame THEN {
MBVM.CopyRead[from: f, to: @globalFrame, nwords: SIZE[PrincOps.GlobalFrame]];
currentFrame ← f;
};
RETURN[@globalFrame]
};
END.