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:
ROPE ←
NIL] = {
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:
ROPE ←
NIL] = {
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: BOOL ← FALSE;
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: CHAR ← IF 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];
};