csl.red 7.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247
  1. module csl; % Support for fast floating point arithmetic in CSL.
  2. imports ash, ash1, logand, msd;
  3. exports msd!:;
  4. fluid '(!!nbfpd);
  5. remflag ('(fl2bf msd!: fix2 rndpwr timbf),'lose);
  6. symbolic smacro procedure fix2 u; fix u;
  7. symbolic smacro procedure lshift(m,d); ash(m,d);
  8. symbolic smacro procedure ashift(m,d); ash1(m,d);
  9. symbolic smacro procedure land(a,b); logand(a,b);
  10. symbolic smacro procedure msd!: u; msd u;
  11. symbolic smacro procedure make!:ibf (mt, ep);
  12. '!:rd!: . (mt . ep);
  13. fluid '(!:bprec!:);
  14. symbolic smacro procedure rndpwr j;
  15. begin
  16. scalar !#w; % I use an odd name here to avoid clashes (smacro)
  17. % !#w := mt!: j;
  18. !#w := cadr j;
  19. if !#w = 0 then return make!:ibf(0, 0);
  20. !#w := inorm(!#w, !:bprec!:);
  21. % return make!:ibf(car !#w, cdr !#w + ep!: j)
  22. return make!:ibf(car !#w, cdr !#w + cddr j)
  23. end;
  24. % This is introduced as a privately-named function and an associated
  25. % smacro to avoid unwanted interactions between 3 versions of this
  26. % function: the one here, the version of this code compiled into C, and
  27. % the original version in arith.red. Note thus that CSL_normbf is not
  28. % flagged as 'lose here (but it will be when a version compiled into
  29. % C exists), and the standard version of normbf will still get compiled
  30. % in arith.red, but all references to it will get turned into calls
  31. % to CSL_normbf. The SMACRO does not need a 'lose flag either.
  32. symbolic procedure CSL_normbf x;
  33. begin
  34. scalar mt,s;
  35. integer ep;
  36. % Note I write out mt!: and ep!: here because the smacros for them are
  37. % not yet available.
  38. if (mt := cadr x)=0 then return '(!:rd!: 0 . 0);
  39. if mt<0 then <<mt := -mt; s := t>>;
  40. ep := lsd mt;
  41. mt := lshift(mt, -ep);
  42. if s then mt := -mt;
  43. ep := ep + cddr x;
  44. return make!:ibf(mt,ep)
  45. end;
  46. symbolic smacro procedure normbf x; CSL_normbf x;
  47. symbolic procedure CSL_timbf(u, v);
  48. begin
  49. scalar m;
  50. % m := mt!: u * mt!: v;
  51. m := cadr u * cadr v;
  52. if m = 0 then return '(!:rd!: 0 . 0);
  53. m := inorm(m, !:bprec!:);
  54. % return make!:ibf(car m, cdr m + ep!: u + ep!: v)
  55. return make!:ibf(car m, cdr m + cddr u + cddr v)
  56. end;
  57. symbolic smacro procedure timbf(u, v); CSL_timbf(u, v);
  58. symbolic procedure fl2bf x;
  59. begin scalar u;
  60. u := frexp x;
  61. x := cdr u; % mantissa between 0.5 and 1
  62. u := car u; % exponent
  63. x := fix(x*2**!!nbfpd);
  64. return normbf make!:ibf(x,u-!!nbfpd)
  65. end;
  66. flag ('(fl2bf msd!: fix2 rndpwr timbf), 'lose);
  67. set!-print!-precision 14;
  68. % The following definition is appropriate for MSDOS, and the value of
  69. % !!maxbflexp should be OK for all IEEE systems. BEWARE if you have a
  70. % computer with non-IEEE arithmetic, and worry a bit about !!flexperr
  71. % (which is hardly ever used anyway...).
  72. % I put this here to avoid having arith.red do a loop that is terminated
  73. % by a floating point exception, since as of Nov 1994 CSL built using
  74. % Watcom C 10.0a can not recover from such errors more than (about) ten
  75. % times in any one run - this avoids that during system building.
  76. global '(!!flexperr !!!~xx !!maxbflexp);
  77. remflag('(find!!maxbflexp), 'lose);
  78. symbolic procedure find!!maxbflexp();
  79. << !!flexperr := t;
  80. !!!~xx := expt(2.0, 1023);
  81. !!maxbflexp := 1022 >>;
  82. flag('(find!!maxbflexp), 'lose);
  83. remflag('(copyd), 'lose);
  84. symbolic procedure copyd(new,old);
  85. % Copy the function definition from old id to new.
  86. begin scalar x;
  87. x := getd old;
  88. % If loading with !*savedef = '!*savedef then the actual definitions
  89. % do not get loaded, but the source forms do...
  90. if null x then <<
  91. if not (!*savedef = '!*savedef)
  92. then rerror('rlisp,1,list(old,"has no definition in copyd"))>>
  93. else << putd(new,car x,cdr x);
  94. if flagp(old, 'lose) then flag(list new, 'lose) >>;
  95. % The transfer of the saved definition is needed if the REDUCE "patch"
  96. % mechanism is to work fully properly.
  97. if (x := get(old, '!*savedef)) then put(new, '!*savedef, x);
  98. return new
  99. end;
  100. flag('(copyd), 'lose);
  101. smacro procedure int2id x; compress list('!!, x);
  102. smacro procedure id2int x; car explode2n x;
  103. smacro procedure bothtimes x; eval!-when((compile load eval), x);
  104. smacro procedure compiletime x; eval!-when((compile eval), x);
  105. smacro procedure loadtime x; eval!-when((load eval), x);
  106. smacro procedure csl x; x;
  107. smacro procedure psl x; nil;
  108. symbolic macro procedure printf u;
  109. list('printf1, cadr u, 'list . cddr u);
  110. symbolic procedure printf1(fmt, args);
  111. % this is the inner works of print formatting.
  112. % the special sequences that can occur in format strings are
  113. % %b do that many spaces
  114. % %c next arg is a numeric character code. display character
  115. % * %f do a terpri() unless posn()=0
  116. % %l prin2 items from given list, blank separated
  117. % * %n do a terpri()
  118. % %o print in octal
  119. % %p print using prin1
  120. % %t do a ttab to move to given column
  121. % %w use prin2
  122. % %x print in hexadecimal
  123. % * %% print a '%' character (items marked * do not use an arg).
  124. begin
  125. scalar a, c;
  126. fmt := explode2 fmt;
  127. while fmt do <<
  128. c := car fmt;
  129. fmt := cdr fmt;
  130. if c = '!% then <<
  131. c := car fmt;
  132. fmt := cdr fmt;
  133. if c = '!f then << if not zerop posn() then terpri() >>
  134. else if c = '!n then terpri()
  135. else if c = '!% then prin2 c
  136. else <<
  137. a := car args;
  138. args := cdr args;
  139. if c = '!b then spaces a
  140. else if c = '!c then tyo a
  141. else if c = '!l then <<
  142. if not atom a then <<
  143. prin2 car a;
  144. for each w in cdr a do << prin2 " "; prin2 w >> >> >>
  145. else if c = '!o then prinoctal a
  146. else if c = '!p then prin1 a
  147. else if c = '!t then ttab a
  148. else if c = '!w then prin2 a
  149. else if c = '!x then prinhex a
  150. else rerror('cslrend,1,list(c,"bad format character")) >> >>
  151. else prin2 c >>
  152. end;
  153. symbolic macro procedure bldmsg u;
  154. list('bldmsg1, cadr u, 'list . cddr u);
  155. symbolic procedure bldstring r;
  156. begin
  157. scalar w;
  158. w := '(!");
  159. while r do <<
  160. w := car r . w;
  161. if car r eq '!" then w := '!" . w;
  162. r := cdr r >>;
  163. return compress ('!" . w)
  164. end;
  165. symbolic procedure bldcolumn(s, n);
  166. if null s or eqcar(s, !$eol!$) then n
  167. else bldcolumn(cdr s, n+1);
  168. symbolic procedure bldmsg1(fmt, args);
  169. begin
  170. scalar a, c, r;
  171. fmt := explode2 fmt;
  172. while fmt do <<
  173. c := car fmt;
  174. fmt := cdr fmt;
  175. if c = '!% then <<
  176. c := car fmt;
  177. fmt := cdr fmt;
  178. if c = '!f then <<
  179. if not zerop bldcolumn(r, 0) then r := !$eol!$ . r >>
  180. else if c = '!n then r := !$eol!$ . r
  181. else if c = '!% then r := c . r
  182. else <<
  183. a := car args;
  184. args := cdr args;
  185. if c = '!b then for i := 1:a do r := '! . r
  186. else if c = '!c then r := a . r
  187. else if c = '!l then <<
  188. if not atom a then <<
  189. r := append(reverse explode2 car a, r);
  190. for each w in cdr a do <<
  191. r := '! . r;
  192. r := append(reverse explode2 w, r) >> >> >>
  193. else if c = '!o then r := append(reverse explodeoctal a, r)
  194. else if c = '!p then r := append(reverse explode a, r)
  195. else if c = '!t then while bldcolumn(r, 0)<a do r := '! . r
  196. else if c = '!w then r := append(reverse explode2 a, r)
  197. else if c = '!x then r := append(reverse explodehex a, r)
  198. else rerror('cslrend,1,list(c,"bad format character")) >> >>
  199. else r := c . r >>;
  200. return bldstring r
  201. end;
  202. put('gc, 'simpfg, '((t (verbos t)) (nil (verbos nil))));
  203. switch gc;
  204. endmodule;
  205. end;