fortpri.red 9.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290
  1. module fortpri; % FORTRAN output package for expressions.
  2. % Author: Anthony C. Hearn.
  3. % Modified by: James Davenport after Francoise Richard, April 1988.
  4. % Herbert Melenk (introducing C output style), October 1994
  5. % Copyright (c) 1991 RAND. All rights reserved.
  6. fluid '(!*fort
  7. !*fortupper
  8. !*period
  9. scountr
  10. explis
  11. fbrkt
  12. fvar
  13. nchars
  14. svar
  15. posn!*
  16. fortlang!*);
  17. switch fortupper;
  18. global '(card_no
  19. charassoc!*
  20. fort_width
  21. fort_lang
  22. spare!*
  23. varnam!*);
  24. % The global fort_exponent is defined in the module arith/smlbflot.
  25. % Global variables initialized in this section.
  26. % SPARE!* should be set in the system dependent code module.
  27. card_no:=20;
  28. charassoc!* :=
  29. '((!A . !a) (!B . !b) (!C . !c) (!D . !d) (!E . !e) (!F . !f)
  30. (!G . !g) (!H . !h) (!I . !i) (!J . !j) (!K . !k) (!L . !l)
  31. (!M . !m) (!N . !n) (!O . !o) (!P . !p) (!Q . !q) (!R . !r)
  32. (!S . !s) (!T . !t) (!U . !u) (!V . !v) (!W . !w) (!X . !x)
  33. (!Y . !y) (!Z . !z));
  34. fort_width := 70;
  35. posn!* := 0;
  36. varnam!* := 'ans;
  37. fort_lang := 'fort;
  38. flag ('(card_no fort_width fort_lang),'share);
  39. put('fort_array,'stat,'rlis);
  40. flag('(fort_array),'flagop);
  41. symbolic procedure varname u;
  42. % Sets the default variable assignment name.
  43. if not idp car u then typerr(car u,"identifier")
  44. else varnam!* := car u;
  45. rlistat '(varname);
  46. symbolic procedure flength(u,chars);
  47. if chars<0 then chars
  48. else if atom u
  49. then chars-if numberp u then if fixp u then flatsizec u+1
  50. else flatsizec u
  51. else flatsizec((lambda x; if x then x else u)
  52. get(u,'prtch))
  53. else flength(car u,flenlis(cdr u,chars)-2);
  54. symbolic procedure flenlis(u,chars);
  55. if null u then chars
  56. else if chars<0 then chars
  57. else if atom u then flength(u,chars)
  58. else flenlis(cdr u,flength(car u,chars));
  59. symbolic procedure fmprint(l,p);
  60. begin scalar x,w;
  61. if null l then return nil
  62. else if atom l then <<
  63. if l eq 'e then return
  64. % if fortlang!*='c then "exp(1.0)" else "EXP(1.0)";
  65. fprin2!* "EXP(1.0)";
  66. if fixp l and !*period then return fmprint(i2rd!* l,p);
  67. if not numberp l or
  68. not(l<0) then return fprin2!* l;
  69. fprin2!* "(";
  70. fbrkt := nil . fbrkt;
  71. fprin2!* l;
  72. fprin2!* ")";
  73. return fbrkt := cdr fbrkt >>
  74. else if stringp l then return fprin2!* l
  75. else if not atom car l then fmprint(car l,p)
  76. else if x := get(car l,'fort)
  77. then return apply2(x,l,p)
  78. else if ((x := get(car l,'pprifn))
  79. and not((x := apply2(x,l,p)) eq 'failed)) or
  80. ((x := get(car l,'prifn))
  81. and not((x := apply1(x,l)) eq 'failed))
  82. then return x
  83. else if x := get(car l,'infix) then <<
  84. p := not(x>p);
  85. if p then <<fprin2!* "("; fbrkt := nil . fbrkt>>;
  86. fnprint(car l,x,cdr l);
  87. if p then <<fprin2!* ")"; fbrkt := cdr fbrkt>>;
  88. return >>
  89. else fprin2!* car l;
  90. w:= fortlang!* = 'c and flagp(car l,'fort_array);
  91. fprin2!* if w then "[" else "(";
  92. fbrkt := nil . fbrkt;
  93. x := !*period;
  94. % Assume no period printing for non-operators (e.g., matrices).
  95. if gettype car l neq 'operator or flagp(car l,'fort_array)
  96. then !*period := nil;
  97. if cdr l then fnprint(if w then "][" else '!*comma!*,0,cdr l);
  98. !*period := x;
  99. fprin2!* if w then "]" else ")";
  100. return fbrkt := cdr fbrkt
  101. end;
  102. symbolic procedure fnprint(op,p,l);
  103. begin
  104. if op eq 'expt then return fexppri(p,l)
  105. else if not get(op,'alt) then <<
  106. fmprint(car l,p);
  107. l := cdr l >>;
  108. for each v in l do <<
  109. if atom v or not (op eq get(car v,'alt)) then foprin op;
  110. fmprint(v,p) >>
  111. end;
  112. symbolic procedure fexppri(p,l);
  113. % Next line added by James Davenport after Francoise Richard.
  114. if car l eq 'e then fmprint('exp . cdr l,p)
  115. % C entry by Herbert Melenk.
  116. else if fortlang!*='c then
  117. if fixp cadr l and cadr l >0 and cadr l<4 then
  118. fmprint('times . for i:=1:cadr l collect car l,p)
  119. else fmprint('pow.l,p)
  120. else begin scalar pperiod;
  121. fmprint(car l,p);
  122. foprin 'expt;
  123. pperiod := !*period;
  124. if numberp cadr l then !*period := nil else !*period := t;
  125. fmprint(cadr l,p);
  126. !*period := pperiod
  127. end;
  128. put('pow,'simpfn,'simpiden);
  129. symbolic procedure foprin op;
  130. (if null x then fprin2!* op else fprin2!* x) where x=get(op,'prtch);
  131. symbolic procedure fvarpri(u,v,w);
  132. %prints an assignment in FORTRAN notation;
  133. begin integer scountr,llength,nchars; scalar explis,fvar,svar;
  134. fortlang!* := reval fort_lang;
  135. if not(fortlang!* memq '(fort c)) then
  136. typerr(fortlang!*,"target language");
  137. if not posintegerp card_no
  138. then typerr(card_no,"FORTRAN card number");
  139. if not posintegerp fort_width
  140. then typerr(fort_width,"FORTRAN line width");
  141. llength := linelength fort_width;
  142. if stringp u
  143. then return <<fprin2!* u;
  144. if w eq 'only then fterpri(t);
  145. linelength llength>>;
  146. if eqcar(u,'!*sq) then u := prepsq!* sqhorner!* cadr u;
  147. scountr := 0;
  148. nchars := if fortlang!* = 'c then 999999
  149. else ((linelength nil-spare!*)-12)*card_no;
  150. %12 is to allow for indentation and end of line effects;
  151. svar := varnam!*;
  152. fvar := if null v then (if fortlang!*='fort then svar else nil)
  153. else car v;
  154. if posn!*=0 and w then fortpri(fvar,u,w)
  155. else fortpri(nil,u,w);
  156. % should mean expression preceded by a string.
  157. linelength llength
  158. end;
  159. symbolic procedure fortpri(fvar,xexp,w);
  160. begin scalar fbrkt;
  161. if eqcar(xexp,'list)
  162. then <<posn!* := 0;
  163. fprin2!* "C ***** INVALID FORTRAN CONSTRUCT (";
  164. fprin2!* car xexp;
  165. return fprin2!* ") NOT PRINTED">>;
  166. if flength(xexp,nchars)<0
  167. then xexp := car xexp . fout(cdr xexp,car xexp,w);
  168. if fvar
  169. then <<posn!* := 0;
  170. fprin2!* " ";
  171. fmprint(fvar,0);
  172. fprin2!* "=">>;
  173. fmprint(xexp,0);
  174. if fortlang!*='fort and w or w='last then fterpri(w)
  175. end;
  176. symbolic procedure fout(args,op,w);
  177. begin integer ncharsl; scalar distop,x,z;
  178. ncharsl := nchars;
  179. if op memq '(plus times) then distop := op;
  180. while args do
  181. <<x := car args;
  182. if atom x and (ncharsl := flength(x,ncharsl))
  183. or (null cdr args or distop)
  184. and (ncharsl := flength(x,ncharsl))>0
  185. then z := x . z
  186. else if distop and flength(x,nchars)>0
  187. then <<z := fout1(distop . args,w) . z;
  188. args := list nil>>
  189. else <<z := fout1(x,w) . z;
  190. ncharsl := flength(op,ncharsl)>>;
  191. ncharsl := flength(op,ncharsl);
  192. args := cdr args>>;
  193. return reversip!* z
  194. end;
  195. symbolic procedure fout1(xexp,w);
  196. begin scalar fvar;
  197. fvar := genvar();
  198. explis := (xexp . fvar) . explis;
  199. fortpri(fvar,xexp,w);
  200. return fvar
  201. end;
  202. % If we are in a comment, we want to continue to stay in one,
  203. % Even if there's a formula. That's the purpose of this flag
  204. % Added by James Davenport after Francoise Richard.
  205. global '(comment!*);
  206. symbolic procedure fprin2!* u;
  207. % FORTRAN output of U.
  208. begin integer m,n;
  209. if posn!*=0 then comment!* :=
  210. stringp u and cadr(explode u) eq 'C;
  211. n := flatsizec u;
  212. m := posn!*+n;
  213. if fixp u and !*period then m := m+1;
  214. if m<(linelength nil-spare!*) then posn!* := m
  215. else <<terpri();
  216. if comment!* then << fprin2 "C"; spaces 4 >>
  217. else spaces 5;
  218. prin2 if fortlang!*='c then " " else ". ";
  219. posn!* := n+7>>;
  220. fprin2 u;
  221. if fixp u and !*period then prin2 "."
  222. end;
  223. symbolic procedure prin2!-downcase u;
  224. for each c in explode2 u do
  225. if liter c then prin2 red!-char!-downcase c else prin2 c;
  226. symbolic procedure prin2!-upcase u;
  227. for each c in explode2 u do
  228. if liter c then prin2 red!-char!-upcase c else prin2 c;
  229. symbolic procedure fprin2 u;
  230. % Prints id or string u so that case of all characters depends on
  231. % !*fortupper. Note !*lower setting only relevant here for PSL.
  232. (if !*fortupper then prin2!-upcase u else prin2!-downcase u)
  233. where !*lower = nil;
  234. symbolic procedure red!-char!-downcase u;
  235. (if x then cdr x else u) where x = atsoc(u,charassoc!*);
  236. symbolic procedure red!-char!-upcase u;
  237. (if x then car x else u) where x = rassoc(u,charassoc!*);
  238. symbolic procedure fterpri(u);
  239. <<if not(posn!*=0) and u then terpri();
  240. posn!* := 0>>;
  241. symbolic procedure genvar;
  242. intern compress append(explode svar,explode(scountr := scountr + 1));
  243. mkop 'no_period; % for printing of expressions with period locally off.
  244. put('no_period,'fort,'fo_no_period);
  245. symbolic procedure fo_no_period(u,p);
  246. begin scalar !*period; fmprint(cadr u,p) end;
  247. endmodule;
  248. end;