-- File: LongStringsB.Mesa
-- Edited by Sandman on July 1, 1980 8:40 AM
-- Edited by Forrest on October 16, 1980 4:21 PM
-- Edited by Johnsson on 5-Dec-80 14:55:50
DIRECTORY
Inline USING [BITAND, DIVMOD],
LongString USING [AppendChar, AppendString],
Mopcodes USING [zKFCB, zPOP],
SDDefs USING [sULongDivMod];
LongStringsB: PROGRAM
IMPORTS Inline, LongString EXPORTS LongString = PUBLIC
BEGIN OPEN LongString;
Overflow: SIGNAL = CODE;
InvalidNumber: SIGNAL = CODE;
NUL: CHARACTER = 0C;
Space: CHARACTER = ' ;
UpperCase: PROCEDURE [c: CHARACTER] RETURNS [CHARACTER] =
BEGIN IF c IN ['a..'z] THEN c ← c + ('A - 'a); RETURN[c] END;
LowerCase: PROCEDURE [c: CHARACTER] RETURNS [CHARACTER] =
BEGIN IF c IN ['A..'Z] THEN c ← c + ('a - 'A); RETURN[c] END;
CompareStrings: PROCEDURE [s1, s2: LONG STRING, ignoreCase: BOOLEAN ← TRUE]
RETURNS [INTEGER] =
BEGIN
i: CARDINAL;
l1: CARDINAL = s1.length;
l2: CARDINAL = s2.length;
c1, c2: CHARACTER;
FOR i IN [0..MIN[l1, l2]) DO
c1 ← s1[i];
c2 ← s2[i];
IF ignoreCase AND c1 # c2 THEN BEGIN c1 ← LowerCase[c1]; c2 ← LowerCase[c2]; END;
SELECT c1 FROM < c2 => RETURN[-1]; > c2 => RETURN[1]; ENDCASE;
ENDLOOP;
RETURN[SELECT l1 FROM < l2 => -1, > l2 => 1, ENDCASE => 0]
END;
StringToNumber: PROCEDURE [s: LONG STRING, radix: CARDINAL ← 10] RETURNS [v: UNSPECIFIED] =
BEGIN OPEN Inline;
char: CHARACTER;
cp: CARDINAL ← 0;
v8, v10: CARDINAL ← 0;
neg: BOOLEAN ← FALSE;
getchar: PROCEDURE =
BEGIN char ← s[cp]; IF (cp ← cp + 1) > s.length THEN char ← NUL; END;
getchar[];
WHILE char <= Space DO
IF char = NUL THEN SIGNAL InvalidNumber; getchar[]; ENDLOOP;
IF char = '- THEN BEGIN neg ← TRUE; getchar[] END;
WHILE char IN ['0..'9] DO
v10 ← v10*10 + (char - '0); v8 ← v8*8 + (char - '0); getchar[]; ENDLOOP;
BEGIN
SELECT LOOPHOLE[BITAND[char, 137B], CHARACTER] FROM
NUL => GOTO noexponent;
'B => BEGIN v ← v8; radix ← 8; END;
'D => BEGIN v ← v10; radix ← 10; END;
ENDCASE => GOTO noexponent;
getchar[];
v10 ← 0;
WHILE char IN ['0..'9] DO v10 ← v10*10 + char - '0; getchar[]; ENDLOOP;
THROUGH [1..v10] DO v ← v*radix ENDLOOP;
EXITS noexponent => v ← IF radix = 8 THEN v8 ELSE v10;
END;
IF char # NUL THEN SIGNAL InvalidNumber;
IF neg THEN RETURN[-v];
END;
AppendNumber: PROCEDURE [s: LONG STRING, n: CARDINAL, radix: CARDINAL] =
BEGIN
xn: PROCEDURE [n: CARDINAL] =
BEGIN
r: CARDINAL;
[n, r] ← Inline.DIVMOD[n, radix];
IF n # 0 THEN xn[n];
IF r > 9 THEN r ← r + 'A - '0 - 10;
AppendChar[s, r + '0];
END;
xn[n];
END;
AppendDecimal: PROCEDURE [s: LONG STRING, n: INTEGER] =
BEGIN
IF n < 0 THEN
BEGIN
IF n = LAST[INTEGER] THEN BEGIN AppendString[s, "-32768"L]; RETURN END;
AppendChar[s, '-];
n ← -n
END;
AppendNumber[s, n, 10];
END;
AppendOctal: PROCEDURE [s: LONG STRING, n: UNSPECIFIED] =
BEGIN AppendNumber[s, n, 8]; AppendChar[s, 'B]; END;
AppendLongDecimal: PROCEDURE [s: LONG STRING, n: LONG INTEGER] =
BEGIN
IF n < 0 THEN
BEGIN
IF n = LAST[LONG INTEGER] THEN
BEGIN AppendString[s, "-2147483648"L]; RETURN END;
AppendChar[s, '-];
n ← -n
END;
AppendLongNumber[s, n, 10];
END;
AppendLongNumber: PROCEDURE [s: LONG STRING, n: LONG UNSPECIFIED, radix: CARDINAL] =
BEGIN OPEN Mopcodes;
DivMod: PROCEDURE [n, d: LONG CARDINAL]
RETURNS [q: LONG CARDINAL, r: INTEGER] = MACHINE CODE
BEGIN zKFCB, SDDefs.sULongDivMod; zPOP END;
xn: PROCEDURE [n: LONG CARDINAL] =
BEGIN
r: CARDINAL;
[n, r] ← DivMod[n, radix];
IF n # 0 THEN xn[n];
IF r > 9 THEN r ← r + 'A - '0 - 10;
AppendChar[s, r + '0];
END;
xn[n];
END;
StringToLongNumber: PROCEDURE [s: LONG STRING, radix: CARDINAL]
RETURNS [v: LONG CARDINAL] =
BEGIN OPEN Inline;
char: CHARACTER;
cp: CARDINAL ← 0;
exp: CARDINAL;
v8, v10: LONG INTEGER ← 0;
neg: BOOLEAN ← FALSE;
getchar: PROCEDURE =
BEGIN char ← s[cp]; IF (cp ← cp + 1) > s.length THEN char ← NUL; END;
getchar[];
WHILE char <= Space DO
IF char = NUL THEN SIGNAL InvalidNumber; getchar[]; ENDLOOP;
IF char = '- THEN BEGIN neg ← TRUE; getchar[] END;
WHILE char IN ['0..'9] DO
v10 ← v10*10 + CARDINAL[char - '0];
v8 ← v8*8 + CARDINAL[char - '0];
getchar[];
ENDLOOP;
BEGIN
SELECT LOOPHOLE[BITAND[char, 137B], CHARACTER] FROM
NUL => GOTO noexponent;
'B => BEGIN v ← v8; radix ← 8; END;
'D => BEGIN v ← v10; radix ← 10; END;
ENDCASE => GOTO noexponent;
getchar[];
exp ← 0;
WHILE char IN ['0..'9] DO exp ← exp*10 + char - '0; getchar[]; ENDLOOP;
THROUGH [1..exp] DO v ← v*radix ENDLOOP;
EXITS noexponent => v ← IF radix = 8 THEN v8 ELSE v10;
END;
IF char # NUL THEN SIGNAL InvalidNumber;
IF neg THEN RETURN[-v];
END;
END....