-- file: RESIOPack.mesa Edited by Bruce, September 22, 1980 10:15 AM DIRECTORY Ascii USING [CR, SP], Format USING [NumberFormat], Inline USING [LongNumber], RESOut USING [MakeRoom, PChar], String USING [AppendLongNumber, AppendNumber, SubString]; RESIOPack: PROGRAM IMPORTS RESOut, String EXPORTS RESOut = BEGIN OPEN RESOut; 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 [ s: STRING, num: CARDINAL, indent: CARDINAL ← 2] = BEGIN extra: CARDINAL ← Log10[num]; PNext[s, extra+2, indent]; PString[": "L]; PUnsigned[num]; END; PNextNull: PUBLIC PROCEDURE [ s: STRING, val, null: UNSPECIFIED, indent: CARDINAL ← 2] = BEGIN extra: CARDINAL ← IF val = null THEN 4 ELSE Log10[val]; PNext[s, extra+2, indent]; PString[": "L]; PNull[val, null]; END; PNextOctal: PUBLIC PROCEDURE [ s: STRING, num: CARDINAL, indent: CARDINAL ← 2] = BEGIN extra: CARDINAL ← Log8[num]; IF num > 7 THEN extra ← extra+1; PNext[s, extra+2, indent]; PString[": "L]; POctal[num]; END; PNextLong: PUBLIC PROCEDURE [ s: STRING, num: LONG INTEGER, indent: CARDINAL ← 2] = BEGIN neg: BOOLEAN ← num < 0; extra: CARDINAL; extra ← IF neg THEN LongLog10[-num]+1 ELSE LongLog10[num]; PNext[s, extra+2, indent]; PString[": "L]; PLongNumber[num, [base: 10, unsigned: FALSE, zerofill: FALSE, columns: 0]]; END; PDecimal: PUBLIC PROCEDURE [i: INTEGER] = BEGIN BEGIN PNumber[i, [10,FALSE,FALSE,1]] END; END; PNull: PUBLIC PROCEDURE [val, null: UNSPECIFIED] = BEGIN IF val = null THEN PString["Null"L] ELSE PUnsigned[val]; END; PSubString: PUBLIC PROCEDURE [ss: String.SubString] = BEGIN i: CARDINAL; FOR i IN [ss.offset..ss.offset+ss.length) DO PChar[ss.base[i]]; ENDLOOP; END; PNext: PUBLIC PROCEDURE [s: STRING, extra: CARDINAL ← 0, indent: CARDINAL ← 2] = BEGIN PChar[',]; IF MakeRoom[s.length+1+extra, indent] THEN PChar[Ascii.SP]; PString[s]; END; PUnsigned: PUBLIC PROCEDURE [i: CARDINAL] = BEGIN BEGIN PNumber[i, [10,FALSE,TRUE,1]] END; END; POctal: PUBLIC PROCEDURE [i: CARDINAL] = BEGIN PNumber[i, [8,FALSE,TRUE,1]]; IF i > 7 THEN PChar['B]; END; PNumber: PUBLIC PROCEDURE [num: UNSPECIFIED, format: Format.NumberFormat] = BEGIN i: CARDINAL; neg: BOOLEAN ← FALSE; fill: CHARACTER ← (IF format.zerofill THEN '0 ELSE ' ); s: STRING ← [10]; IF INTEGER[num] < 0 AND ~format.unsigned THEN BEGIN num ← -INTEGER[num]; neg ← TRUE END; String.AppendNumber[s, num, format.base]; i ← s.length; IF neg THEN BEGIN i ← i + 1; IF fill = '0 THEN BEGIN PChar['-]; neg ← FALSE END; END; THROUGH (i..format.columns] DO PChar[fill] ENDLOOP; IF neg THEN BEGIN PChar['-]; END; PString[s]; RETURN END; PLongNumber: PUBLIC PROCEDURE [ num: LONG UNSPECIFIED, format: Format.NumberFormat] = BEGIN n: Inline.LongNumber ← LOOPHOLE[num]; i: CARDINAL; neg: BOOLEAN ← FALSE; fill: CHARACTER ← (IF format.zerofill THEN '0 ELSE ' ); s: STRING ← [20]; IF n.li < 0 AND ~format.unsigned THEN BEGIN n.li ← -n.li; neg ← TRUE END; String.AppendLongNumber[s, n.lc, format.base]; i ← s.length; IF neg THEN BEGIN i ← i + 1; IF fill = '0 THEN BEGIN PChar['-]; neg ← FALSE END; END; THROUGH (i..format.columns] DO PChar[fill] ENDLOOP; IF neg THEN BEGIN PChar['-]; END; PString[s]; RETURN END; PCr: PUBLIC PROCEDURE = BEGIN PChar[Ascii.CR]; END; PString: PUBLIC PROCEDURE [s: STRING] = BEGIN i: CARDINAL; FOR i IN [0..s.length) DO PChar[s[i]]; ENDLOOP; END; END.