MiscRegistryImpl.mesa
Copyright Ó 1988, 1990, 1991 by Xerox Corporation. All rights reserved.
Willie-sue, December 3, 1990 11:37 am PST
DIRECTORY
Convert USING [NetFormat, RopeFromXNSHost],
ProcessorFace USING [processorID],
Rope,
ThisMachine USING [],
ThisMachineRegistry;
MiscRegistryImpl: CEDAR MONITOR
IMPORTS Convert, ProcessorFace, Rope
EXPORTS ThisMachine, ThisMachineRegistry ~ BEGIN
ROPE: TYPE = Rope.ROPE;
ThisMachineRef: TYPE = ThisMachineRegistry.ThisMachineRef;
registeredTMProcs: LIST OF ThisMachineRef ¬ NIL;
Exported to ThisMachine
Name: PUBLIC PROC [which: ATOM] RETURNS [rope: ROPE ¬ NIL] = {
thisProcs: ThisMachineRef ¬ FindProcs[which];
IF thisProcs # NIL THEN rope ¬ thisProcs.Name[];
};
Address: PUBLIC PROC [which: ATOM] RETURNS [rope: ROPE ¬ NIL] = {
thisProcs: ThisMachineRef ¬ FindProcs[which];
IF thisProcs # NIL THEN rope ¬ thisProcs.Address[];
};
ProcessorID: PUBLIC PROC [which: ATOM] RETURNS [rope: ROPE ¬ NIL]
~ {
this is done here for now, but we can change it if we want to later
Processor ID and XNS Host number are the same. Perhaps this is a crock, but it sure makes the code shorter! — ajd
format: Convert.NetFormat ¬ SELECT which FROM
NIL, $Octal => octal,
$Decimal, $ProductSoftware => productSoftware,
$Hex => hex,
ENDCASE => ERROR;
rope ¬ Convert.RopeFromXNSHost[LOOPHOLE[ProcessorFace.processorID], format];
IF (format = octal) THEN {
Ugh. Convert adds the trailing 'B, and ThisMachine doesn't.
length: INT ¬ Rope.Length[rope];
IF (length > 0) AND (Rope.Fetch[rope, length-1] = 'B)
THEN rope ¬ Rope.Substr[rope, 0, length-1];
};
};
Exported to ThisMachineRegistry
RegisterThisMachineProcs: PUBLIC ENTRY PROC[newProcs: ThisMachineRef] = {
ENABLE UNWIND => NULL;
registeredTMProcs ¬ CONS[newProcs, registeredTMProcs];
};
GetThisMachineProcs: PUBLIC ENTRY PROC RETURNS[LIST OF ThisMachineRef] = {
ENABLE UNWIND => NULL;
RETURN[registeredTMProcs]
};
Utilities
FindProcs: ENTRY PROC[which: ATOM] RETURNS[ThisMachineRef] = {
ENABLE UNWIND => NULL;
reallyUse: ATOM ¬ which;
this: ThisMachineRef;
Try: PROC RETURNS[ThisMachineRef] = {
FOR tmL: LIST OF ThisMachineRef ¬ registeredTMProcs, tmL.rest UNTIL tmL=NIL DO
IF reallyUse = tmL.first.which THEN RETURN[tmL.first];
ENDLOOP;
RETURN[NIL];
};
SELECT which FROM
$Pup => reallyUse ¬ $pup;
$XNS => reallyUse ¬ $xns;
NIL, $Arpa => reallyUse ¬ $ip;
ENDCASE => NULL;
IF reallyUse = NIL THEN RETURN[NIL];
IF ( this ¬ Try[] ) # NIL THEN RETURN[this];
IF ( which = NIL ) THEN reallyUse ¬ $ip;
RETURN[ Try[] ];
};
END.
Here's some old code that works, in case we ever need to separate ProcessorID and XNSHost.
ProcessorID: PUBLIC PROC [which: ATOM] RETURNS [rope: ROPENIL] = {
text: REF TEXT ← RefText.ObtainScratch[maxDigits];
me: ProcessorFace.ProcessorID ← ProcessorFace.processorID;
words: Words;
format: Format;
TRUSTED { words ← LOOPHOLE[@me]; };
SELECT which FROM
NIL, $Octal => format ← octal;
$Decimal, $ProductSoftware => format ← productSoftware;
$Hex => format ← hex;
ENDCASE => RETURN;
text ← AppendField[text, words, SIZE[ProcessorFace.ProcessorID], format];
rope ← Rope.FromRefText[text];
RefText.ReleaseScratch[text];
};
maxDigits: NAT = MAX[16];
Digits: TYPE = ARRAY [0..maxDigits) OF NAT;
Format: TYPE = {octal, productSoftware, hex};
Words: TYPE = POINTER TO ARRAY [0..3) OF WORD;
UnrecognizedFormatOption: ERROR = CODE;
This will break on a 32 bit machine.
AppendField: PROC [text: REF TEXT, words: Words, count: NAT, format: Format] RETURNS [REF TEXT] = {
digits: Digits;
base: NAT;
SELECT format FROM
octal => base ← 8;
productSoftware => base ← 10;
hex => base ← 16;
ENDCASE => ERROR UnrecognizedFormatOption;
TRUSTED {
ConvertToDigits[words, count, base, @digits];
text ← AppendDigits[text, @digits, base = 10]; };
IF base = 16 THEN text ← RefText.AppendChar[text, 'H];
RETURN[text];
};
ConvertToDigits: PROC [words: Words, size, base: NAT, digits: POINTER TO Digits] = TRUSTED {
digits^ ← ALL[0];
FOR i: NAT IN [0..size*Basics.bitsPerWord) DO
bit: CARDINAL ← ShiftFieldLeft[words, size, 1];
FOR j: NAT DECREASING IN [0..maxDigits) DO
digits[j] ← digits[j]*2 + bit;
IF digits[j] >= base THEN { digits[j] ← digits[j] - base; bit ← 1; }
ELSE bit ← 0;
ENDLOOP;
ENDLOOP;
};
ShiftFieldLeft: PROC [words: Words, count: NAT, shift: INTEGER]
RETURNS [left: NAT] = TRUSTED {
right: WORD ← 0;
FOR i: NAT DECREASING IN [0..count) DO
left ← Basics.BITSHIFT[words[i], shift - 16];
words[i] ← Basics.BITOR[Basics.BITSHIFT[words[i], shift], right];
right ← left;
ENDLOOP;
};
AppendDigits: PROC [text: REF TEXT, digits: POINTER TO Digits, dashes: BOOL] RETURNS [REF TEXT] = TRUSTED {
something: BOOLFALSE;
FOR i: NAT IN [0..maxDigits) DO
v: NAT ← digits[i];
IF dashes AND something AND (maxDigits - i) MOD 3 = 0 THEN
text ← RefText.AppendChar[text, '-];
IF v # 0 AND ~something THEN {
IF dashes THEN {
SELECT maxDigits - i FROM
1 => text ← RefText.AppendRope[text, "0-00"];
2 => text ← RefText.AppendRope[text, "0-0"];
3 => text ← RefText.AppendRope[text, "0-"];
ENDCASE => NULL; };
IF v > 9 THEN text ← RefText.AppendChar[text, '0]; -- Leading digit for Hex case
something ← TRUE; };
IF something THEN {
c: CHARIF v > 9 THEN v - 10 + 'A ELSE v + '0;
text ← RefText.AppendChar[text, c]; };
ENDLOOP;
IF ~something THEN text ← RefText.AppendChar[text, '0];
RETURN[text];
};
}.