ThisMachineImpl.mesa
Copyright © 1986 by Xerox Corporation. All rights reserved.
Hal Murray, January 23, 1986 9:21:50 pm PST
DIRECTORY
Basics USING [BITOR, BITSHIFT, bitsPerWord],
PupName USING [MyName, MyRope],
ProcessorFace USING [processorID, ProcessorID],
RefText USING [AppendChar, AppendRope, ObtainScratch, ReleaseScratch],
Rope USING [FromRefText, Find, ROPE],
ThisMachine USING [];
ThisMachineImpl: CEDAR PROGRAM
IMPORTS Basics, PupName, ProcessorFace, RefText, Rope
EXPORTS ThisMachine = {
ROPE: TYPE = Rope.ROPE;
Name: PUBLIC PROC [which: ATOM] RETURNS [rope: ROPENIL] = {
SELECT which FROM
NIL, $Pup => {
rope ← PupName.MyName[];
IF Rope.Find[rope, "#"] # -1 THEN RETURN[NIL]; };
ENDCASE => RETURN[NIL];
};
Address: PUBLIC PROC [which: ATOM] RETURNS [rope: ROPE] = {
SELECT which FROM
NIL, $Pup => {
rope ← PupName.MyRope[];
IF Rope.Find[rope, "#0#"] # -1 THEN RETURN[NIL]; };
ENDCASE => RETURN[NIL];
};
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];
};
}.