}
a) MODE {?}NUMBER= UNION (« {L} REAL », « {L} INT »);
b) PROC whole = (NUMBER v, INT width)STRING: CASE v IN « ({L} INT x): (INT length := ABS width - (x < {L} 0 ¦ width > 0 | 1 | 0), {L} INT n := ABS x; IF width = 0 THEN {L} INT m := n; length := 0; WHILE m DO SKIP OD
FI; STRING s := subwhole (n, length); IF length = 0 | char in string (errorchar, LOC INT, s) THEN ABS width * errorchar ELSE (x< {L} 0 | "-" |: width>0 | "+" | "") PLUSTO s; (width /= 0 (ABS width - UPB s) * " " PLUSTO s); s FI)»,
« ({L} REAL x): fixed (x, width, 0) » ESAC;
c) PROC fixed (NUMBER v, INT width, after)STRING: CASE v IN « ({L} REAL x): IF INT length := ABS width - (x < {L} 0 ¦ width>0 | 1 | 0); after >=0 (length> after ¦ width = 0) THEN {L} REAL y = ABS x; IF width =0 THEN length := (after = 0 | 1 | 0); WHILE y + {L}.5* {L}.1 ^ after>={L}10 ^ length DO length +:= 1 OD; length +:= (after = 0 | 0 | after + 1) FI; STRING s := sub fixed (y, length, after); IF char in string (errorchar, LOC INT, s) THEN(length> UPB s y< {L} 10 | "0" PLUSTO s); (x< {L} 0 | "-" |: width>0 | "+" |"") PLUSTO s; (width /= 0 | (ABS width - UPB s) * " " PLUSTO s); s ELIF after> 0 THEN fixed (v, width, after - 1) ELSE ABS width * errorchar FI ELSE undefined; ABS width * errorchar FI», « ({L} INT x): fixed ({L} REAL (x), width, after) » ESAC;
d) PROC float = (NUMBER v, INT width, after, exp)STRING: CASE v IN « ({L} REAL x): IF INT before = ABS width - ABS exp - (after /= 0| after + 1| 0) -2; SIGN before + SIGN after> 0 THEN STRING s, {L} REAL y := ABS x, INT p := 0; {l} standardize(y, before, after, p); s := fixed({K} SIGN x * y, SIGN width * (ABS width - ABS exp - 1),## after) + "10" + whole (p, exp); IF exp = 0 ¦ char in string (errorchar, LOC INT, s) THEN float(x, width, (after /= 0| after - 1|0),## (exp>0 | exp + 1 | exp-1)) ELSE s FI ELSE undefined; ABS width * errorchar FI», « ({L} INT x): float({L} REAL (x), width, after, exp) » ESAC;
e) PROC {?}subwhole = (NUMBER v, INT width)STRING: # returns a string of maximum length 'width' containing a decimal representation of the positive integer 'v' # CASE v IN « ({L} INT x): BEGIN STRING s, {L} INT n := x; WHILE dig char ({S} (n MOD {L} 10)) PLUSTO s; n DO SKIP OD; (UPB s> width | width * errorchar | s) END » ESAC;
f) PROC {?}subfixed = (NUMBER v, INT width, after)STRING: # returns a string of maximum length 'width' containing a rounded decimal representation of the positive real number 'v'; if 'after' is greater than zero, this string contains a decimal point followed by 'after' digits s # CASE v IN « ({L} REAL x): BEGIN STRING s, INT before := 0; {L} REAL y := x + {L}.5 x {L}.1 ^ after; PROC choosedig = (REF {L} REAL y)CHAR: dig char((INT c := {S} ENTIER(y *:= {L}10.0); (c>9 | c := 9);## y -:= {K}c; c)); WHILE y > {L} 10.0 ^ before DO before +:= 1 OD; y /:= {L}10.0 ^ before; TO before DO s PLUSAB choosedig(y) OD; (after> 0 | s PLUSAB "."); TO after DO s PLUSAB choosedig(y) OD; (UPB s> width | width * errorchar | s) END » ESAC;
g) PROC {?}{l} standardize = (REF {L} REAL y, INT before, after, REF INT p)VOID: # adjusts the value of 'y' so that it may be transput according to the format n(before)d, n(after)d ; 'p' is set so that y * 10 ^ p is equal to the original value of 'y' # BEGIN {L} REAL g = {L}10.0 ^ before; {L} REAL h = g * {L}.1; WHILE y > g DO y *:= {L}.1; p +:= 1 OD; (y /= {L} 0.0| WHILE y<h DO y *:= {L}10.0; p-:= l OD); (y + {L}.5 * {L}.1 ^after>=g | y:=h; p +:= 1) END;
h) PROC {?}dig char = (INT x)CHAR: "0123456789abcdef"[x + 1];
i) PROC {?}string to {l} int = (STRING s, INT radix, REF {L} INT i)BOOL: # returns true if the absolute value of the result is < '140 max int # BEGIN {L} INT lr = {K} radix; BOOL safe := TRUE; {L} INT n := {L} 0, {L} INT m = {l} max int lr; {L} INT m1 = {l} max int - m * lr; FOR i FROM 2 TO UPB s WHILE {L} INT dig = {K} char dig(s [i]); safe := n < m ¦ n = m dig <= m1
DO n := n * lr + dig OD; IF safe THEN i := (s[l]="+" | n | -n); TRUE ELSE FALSE FI
END;
j) PROC {?}string to {l} real = (STRING s, REF {L} REAL r)BOOL: # returns true if the absolute value of the result is < '140 max real # BEGIN INT e := UPB s + 1; char in string(" ", e, s); INT p := e; char in string(". ", p, s); INT j := 1, length =0, {L} REAL x := {L} 0.0; # skip leading zeroes: # FOR i FROM 2 TO e -1 WHILE s[i]="0" ¦ s[i] ="." ¦ s[i] ="" DO j := i OD; FOR i FROM j + 1 TO e - 1 WHILE length < {l} real width DO IF s [i] /= "." THEN x := x * {L}10.0 + {K} char dig(s[j := i]); length +:= i FI # all significant digits converted #
OD;
# set preliminary exponent: # INT exp := (p>j | p-j-i | p-j), expart := 0; # convert exponent part: # BOOL safe := IF e< UPB s THEN string to int(s [e + 1: ], 10), expart) ELSE TRUE FI;
# prepare a representation of '140 max real to compare with the L REAL value to be delivered: # {L} REAL max stag := {l} max real, INT max exp := t); {l} standardize(max stag, length, 0, max exp); exp +:= expart; IF safe ¦ (exp> max exp ¦ exp = max exp x> max stag) THEN FALSE ELSE r := (s[1]="+" | x | -x) * {L} 10.0 ^ exp; TRUE FI
END;
k) PROC {?}char dig = (CHAR x)INT: (x = " "|0|INT i; char in string(x, i, "0123456789abcdef"); i - 1);
l) PROC char in string = (CHAR c, REF INT i, STRING s)BOOL: (BOOL found := FALSE; FOR k FROM LWB s TO UPB s WHILE found DO (c = s[k] | i := k; found := TRUE) OD; found);
m) INT {l} int width = # the smallest integral value such that ''140 max int' may be converted without error using the pattern n('140 int width)d # (INT c := 1; WHILE {L}10 ^ (c-1)< {L}.1 * {l} maxint DO c +:= 1 OD; c);
n) INT {l} real width = # the smallest integral value such that different strings are produced by conversion of 'L1.0' and of 'L1.0 + '140 small real' using the pattern d, n('140 real width - i)d # 1 - {S} ENTIER({l} ln({l} small real) / {l} ln({L} 10));
o) INT {l} exp width = # the smallest integral value
such that ''140 max real' may be converted without error using the pattern
d.n('140 real width - i)d e n('140 exp width)d # 1 + {S} ENTIER({l} ln({l}
ln({l} max real)/{l} ln({L} 10))/{l} ln({L} 10));
b) MODE {?}OUTTYPE = © an actual-declarer specifying a mode united from {2.1.3.6.a } a sufficient set of modes none of which is 'void' or contains 'flexible', 'reference to', 'procedure' or 'union of' ©;
c) MODE {?}SIMPLIN = UNION(«REF {L} INT », « REF {L} REAL », « REF {L} COMPL t»,## REF BOOL, « REF {L} BITS », REF CHAR, REF [ ] CHAR, REF STRING);
d) MODE {?}INTYPE = © an actual-declarer specifying a mode united from {2.1.3.6.a } 'reference to flexible row of character' together with a sufficient set of modes each of which is 'reference to' followed by a mode which does not contain 'flexible', 'reference to', 'procedure' or 'union of' ©;
{See the remarks after 10.2.3.1
concerning
the term "sufficient set".}
b) OP {?}STRAIGHTIN = (INTYPE x) [ ] SIMPLIN:## © the result of straightening 'x' ©;
c) The result of "straightening" a given value V is a multiple value W {of one dimension} obtained as follows:
· it is required that V (if it is a name) be not nil;
· a counter i is set to 0:
· V is "traversed" {d} using
· W is composed of, a descriptor ((1, i)) and the elements obtained by traversing V:
· if V is not (is) a name, then the mode of the result is the mode specified by [ ] SIMPLOUT ([ ] SIMPLIN).
d) A value V is "traversed", using a counter i, as follows:
· i is increased
by one:
· the element of W selected by (i) is V:
· for j = l, ...,
u, the element (the subname) of V selected by (j) is traversed using
i;
· for j = l1,
... u1, the multiple value selected {2.1.3.4.i
} by
(the name generated {2.1.3.4.j
} by) the trim (j, (l2,
u2, 0), ..., (ln, un, 0)) is traversed
using i;
· the fields (the
subnames of V referring to the fields) of V1, taken in order,
are traversed using i.