file: RESIOPack.mesa Edited by:
Last Edited by: Sweet, January 8, 1986 10:28:53 am PST
DIRECTORY
Convert USING [RopeFromCard],
ConvertUnsafe USING [SubString],
RESOut USING [Handle, MakeRoom, NumberFormat, PChar],
Rope USING [Fetch, Length, ROPE];
RESIOPack: CEDAR PROGRAM IMPORTS Convert, RESOut, Rope EXPORTS RESOut =
BEGIN OPEN RESOut;
ROPE: TYPE = Rope.ROPE;
Handle: TYPE = RESOut.Handle;
Log10: PUBLIC PROCEDURE [num: CARDINAL] RETURNS [CARDINAL] =
BEGIN
IF num < 1000 THEN
IF num < 10 THEN RETURN[1]
ELSE
IF num >= 100 THEN RETURN[3]
ELSE RETURN[2]
ELSE
IF num >= 10000 THEN RETURN[5]
ELSE RETURN[4];
END;
LongLog10: PUBLIC PROCEDURE [num: LONG CARDINAL] RETURNS [CARDINAL] =
BEGIN
power: ARRAY [1..10] OF LONG CARDINAL =
[0, 1D1, 1D2, 1D3, 1D4, 1D5, 1D6, 1D7, 1D8, 1D9];
u, l, i: CARDINAL;
l ← 1; u ← 11;
UNTIL u < l DO
i ← (l+u)/2;
SELECT power[i] FROM
= num => RETURN [i];
> num => u ← i-1;
ENDCASE => l ← i+1;
ENDLOOP;
RETURN [u]; -- see Knuth, 6.2.1 Exercise 1.
END;
Log8: PUBLIC PROCEDURE [num: CARDINAL] RETURNS [CARDINAL] =
BEGIN
IF num < 1000B THEN
IF num < 10B THEN RETURN[1]
ELSE
IF num >= 100B THEN RETURN[3]
ELSE RETURN[2]
ELSE
IF num >= 100000B THEN RETURN[6]
ELSE
IF num >= 10000B THEN RETURN[5]
ELSE RETURN[4];
END;
LongLog8: PUBLIC PROCEDURE [num: LONG CARDINAL] RETURNS [CARDINAL] =
BEGIN
power: ARRAY [1..11] OF LONG CARDINAL =
[0, 1B1, 1B2, 1B3, 1B4, 1B5, 1B6, 1B7,
1B8, 1B9, 1B10];
u, l, i: CARDINAL;
l ← 1; u ← 11;
UNTIL u < l DO
i ← (l+u)/2;
SELECT power[i] FROM
= num => RETURN [i];
> num => u ← i-1;
ENDCASE => l ← i+1;
ENDLOOP;
RETURN [u];
END;
PNextUnsigned: PUBLIC PROCEDURE [
h: Handle, s: ROPE, num: CARDINAL, indent: CARDINAL ← 2] =
BEGIN
extra: CARDINAL ← Log10[num];
PNext[h, s, extra+2, indent];
PRope[h, ": "];
PUnsigned[h, num];
END;
PNextNull: PUBLIC PROCEDURE [
h: Handle, s: ROPE, val, null: UNSPECIFIED, indent: CARDINAL ← 2] =
BEGIN
extra: CARDINALIF val = null THEN 4 ELSE Log10[val];
PNext[h, s, extra+2, indent];
PRope[h, ": "];
PNull[h, val, null];
END;
PNextOctal: PUBLIC PROCEDURE [
h: Handle, s: ROPE, num: CARDINAL, indent: CARDINAL ← 2] =
BEGIN
extra: CARDINAL ← Log8[num];
IF num > 7 THEN extra ← extra+1;
PNext[h, s, extra+2, indent];
PRope[h, ": "];
POctal[h, num];
END;
PNextLong: PUBLIC PROCEDURE [
h: Handle, s: ROPE, num: LONG INTEGER, indent: CARDINAL ← 2] =
BEGIN
neg: BOOLEAN ← num < 0;
extra: CARDINAL;
extra ← IF neg THEN LongLog10[-num]+1 ELSE LongLog10[num];
PNext[h, s, extra+2, indent];
PRope[h, ": "];
PLongNumber[h, num,
[base: 10, unsigned: FALSE, zerofill: FALSE, columns: 0]];
END;
PDecimal: PUBLIC PROCEDURE [h: Handle, i: INTEGER] =
BEGIN
BEGIN PNumber[h, i, [10,FALSE,FALSE,1]] END;
END;
PNull: PUBLIC PROCEDURE [h: Handle, val, null: UNSPECIFIED] =
BEGIN
IF val = null THEN PRope[h, "Null"]
ELSE PUnsigned[h, val];
END;
PNext: PUBLIC PROCEDURE [h: Handle, s: ROPE, extra: CARDINAL ← 0, indent: CARDINAL ← 2] =
BEGIN
PChar[h, ',];
IF MakeRoom[h, Rope.Length[s]+1+extra, indent] THEN PChar[h, ' ];
PRope[h, s];
END;
PUnsigned: PUBLIC PROCEDURE [h: Handle, i: CARDINAL] =
BEGIN
BEGIN PNumber[h, i, [10,FALSE,TRUE,1]] END;
END;
POctal: PUBLIC PROCEDURE [h: Handle, i: CARDINAL] =
BEGIN
PNumber[h, i, [8,FALSE,TRUE,1]];
IF i > 7 THEN PChar[h, 'B];
END;
PNumber: PUBLIC PROCEDURE [h: Handle, num: UNSPECIFIED, format: NumberFormat] =
BEGIN
i: CARDINAL;
neg: BOOLEANFALSE;
fill: CHARACTER ← (IF format.zerofill THEN '0 ELSE ' );
s: ROPE;
IF ~format.unsigned AND INTEGER[num] < 0 THEN {
num ← -INTEGER[num]; neg ← TRUE};
s ← Convert.RopeFromCard[from: LONG[CARDINAL[num]], base: format.base, showRadix: FALSE];
i ← Rope.Length[s];
IF neg THEN
BEGIN
i ← i + 1;
IF fill = '0 THEN BEGIN PChar[h, '-]; neg ← FALSE END;
END;
THROUGH (i..format.columns] DO PChar[h, fill] ENDLOOP;
IF neg THEN BEGIN PChar[h, '-]; END;
PRope[h, s];
RETURN
END;
PLongNumber: PUBLIC PROCEDURE [
h: Handle, num: LONG UNSPECIFIED, format: NumberFormat] =
BEGIN
n: LONG CARDINAL ← num;
i: CARDINAL;
neg: BOOLEANFALSE;
fill: CHARACTER ← (IF format.zerofill THEN '0 ELSE ' );
s: ROPE;
IF ~format.unsigned AND LOOPHOLE [num, LONG INTEGER] < 0 THEN
BEGIN n ← -LOOPHOLE [num, LONG INTEGER]; neg ← TRUE END;
s ← Convert.RopeFromCard[from: num, base: format.base, showRadix: FALSE];
i ← Rope.Length[s];
IF neg THEN
BEGIN
i ← i + 1;
IF fill = '0 THEN BEGIN PChar[h, '-]; neg ← FALSE END;
END;
THROUGH (i..format.columns] DO PChar[h, fill] ENDLOOP;
IF neg THEN BEGIN PChar[h, '-]; END;
PRope[h, s];
RETURN
END;
PCr: PUBLIC PROCEDURE [h: Handle] =
BEGIN
PChar[h, '\n];
END;
PRope: PUBLIC PROC [h: Handle, s: ROPE] =
BEGIN
i: INT;
FOR i IN [0..Rope.Length[s]) DO
PChar[h, Rope.Fetch[s, i]];
ENDLOOP;
END;
PSubString: PUBLIC PROC [h: Handle, ss: ConvertUnsafe.SubString] = TRUSTED
BEGIN
i: INT;
FOR i IN [0..ss.length) DO
PChar[h, ss.base[ss.offset + i]];
ENDLOOP;
END;
PLongOctal: PUBLIC PROC [h: Handle, lu: LONG UNSPECIFIED] = {
PLongNumber[h, lu, [base: 8, zerofill: FALSE, unsigned: TRUE, columns: 0]]};
PNil: PUBLIC PROC [h: Handle, p: POINTER] =
BEGIN
IF p = NIL THEN PRope[h, "NIL"] ELSE POctal[h, LOOPHOLE[p]];
END;
PLongNil: PUBLIC PROC [h: Handle, p: LONG POINTER] =
BEGIN
IF p = NIL THEN PRope[h, "NIL"] ELSE PLongOctal[h, p];
END;
PNextNil: PUBLIC PROC [h: Handle, lbl: ROPE, p: POINTER, indent: CARDINAL ← 2] =
BEGIN
IF p = NIL THEN {PNext[h, lbl, 5, indent]; PRope[h, ": NIL"]}
ELSE PNextOctal[h, lbl, LOOPHOLE[p], indent];
END;
PNextLongNil: PUBLIC PROC [h: Handle, lbl: ROPE, p: LONG POINTER, indent: CARDINAL ← 2] =
BEGIN
IF p = NIL THEN {PNext[h, lbl, 5, indent]; PRope[h, ": NIL"]}
ELSE PNextLongOctal[h, lbl, p, indent];
END;
PNextLongOctal: PUBLIC PROC [
h: Handle, s: ROPE, num: LONG UNSPECIFIED, indent: CARDINAL ← 2] =
BEGIN
extra: CARDINAL ← LongLog8[num];
PNext[h, s, extra+2, indent];
PRope[h, ": "];
PLongOctal[h, num];
END;
END.