123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290 |
- module fortpri; % FORTRAN output package for expressions.
- % Author: Anthony C. Hearn.
- % Modified by: James Davenport after Francoise Richard, April 1988.
- % Herbert Melenk (introducing C output style), October 1994
- % Copyright (c) 1991 RAND. All rights reserved.
- fluid '(!*fort
- !*fortupper
- !*period
- scountr
- explis
- fbrkt
- fvar
- nchars
- svar
- posn!*
- fortlang!*);
- switch fortupper;
- global '(card_no
- charassoc!*
- fort_width
- fort_lang
- spare!*
- varnam!*);
- % The global fort_exponent is defined in the module arith/smlbflot.
- % Global variables initialized in this section.
- % SPARE!* should be set in the system dependent code module.
- card_no:=20;
- charassoc!* :=
- '((!A . !a) (!B . !b) (!C . !c) (!D . !d) (!E . !e) (!F . !f)
- (!G . !g) (!H . !h) (!I . !i) (!J . !j) (!K . !k) (!L . !l)
- (!M . !m) (!N . !n) (!O . !o) (!P . !p) (!Q . !q) (!R . !r)
- (!S . !s) (!T . !t) (!U . !u) (!V . !v) (!W . !w) (!X . !x)
- (!Y . !y) (!Z . !z));
- fort_width := 70;
- posn!* := 0;
- varnam!* := 'ans;
- fort_lang := 'fort;
- flag ('(card_no fort_width fort_lang),'share);
- put('fort_array,'stat,'rlis);
- flag('(fort_array),'flagop);
- symbolic procedure varname u;
- % Sets the default variable assignment name.
- if not idp car u then typerr(car u,"identifier")
- else varnam!* := car u;
- rlistat '(varname);
- symbolic procedure flength(u,chars);
- if chars<0 then chars
- else if atom u
- then chars-if numberp u then if fixp u then flatsizec u+1
- else flatsizec u
- else flatsizec((lambda x; if x then x else u)
- get(u,'prtch))
- else flength(car u,flenlis(cdr u,chars)-2);
- symbolic procedure flenlis(u,chars);
- if null u then chars
- else if chars<0 then chars
- else if atom u then flength(u,chars)
- else flenlis(cdr u,flength(car u,chars));
- symbolic procedure fmprint(l,p);
- begin scalar x,w;
- if null l then return nil
- else if atom l then <<
- if l eq 'e then return
- % if fortlang!*='c then "exp(1.0)" else "EXP(1.0)";
- fprin2!* "EXP(1.0)";
- if fixp l and !*period then return fmprint(i2rd!* l,p);
- if not numberp l or
- not(l<0) then return fprin2!* l;
- fprin2!* "(";
- fbrkt := nil . fbrkt;
- fprin2!* l;
- fprin2!* ")";
- return fbrkt := cdr fbrkt >>
- else if stringp l then return fprin2!* l
- else if not atom car l then fmprint(car l,p)
- else if x := get(car l,'fort)
- then return apply2(x,l,p)
- else if ((x := get(car l,'pprifn))
- and not((x := apply2(x,l,p)) eq 'failed)) or
- ((x := get(car l,'prifn))
- and not((x := apply1(x,l)) eq 'failed))
- then return x
- else if x := get(car l,'infix) then <<
- p := not(x>p);
- if p then <<fprin2!* "("; fbrkt := nil . fbrkt>>;
- fnprint(car l,x,cdr l);
- if p then <<fprin2!* ")"; fbrkt := cdr fbrkt>>;
- return >>
- else fprin2!* car l;
- w:= fortlang!* = 'c and flagp(car l,'fort_array);
- fprin2!* if w then "[" else "(";
- fbrkt := nil . fbrkt;
- x := !*period;
- % Assume no period printing for non-operators (e.g., matrices).
- if gettype car l neq 'operator or flagp(car l,'fort_array)
- then !*period := nil;
- if cdr l then fnprint(if w then "][" else '!*comma!*,0,cdr l);
- !*period := x;
- fprin2!* if w then "]" else ")";
- return fbrkt := cdr fbrkt
- end;
- symbolic procedure fnprint(op,p,l);
- begin
- if op eq 'expt then return fexppri(p,l)
- else if not get(op,'alt) then <<
- fmprint(car l,p);
- l := cdr l >>;
- for each v in l do <<
- if atom v or not (op eq get(car v,'alt)) then foprin op;
- fmprint(v,p) >>
- end;
- symbolic procedure fexppri(p,l);
- % Next line added by James Davenport after Francoise Richard.
- if car l eq 'e then fmprint('exp . cdr l,p)
- % C entry by Herbert Melenk.
- else if fortlang!*='c then
- if fixp cadr l and cadr l >0 and cadr l<4 then
- fmprint('times . for i:=1:cadr l collect car l,p)
- else fmprint('pow.l,p)
- else begin scalar pperiod;
- fmprint(car l,p);
- foprin 'expt;
- pperiod := !*period;
- if numberp cadr l then !*period := nil else !*period := t;
- fmprint(cadr l,p);
- !*period := pperiod
- end;
- put('pow,'simpfn,'simpiden);
- symbolic procedure foprin op;
- (if null x then fprin2!* op else fprin2!* x) where x=get(op,'prtch);
- symbolic procedure fvarpri(u,v,w);
- %prints an assignment in FORTRAN notation;
- begin integer scountr,llength,nchars; scalar explis,fvar,svar;
- fortlang!* := reval fort_lang;
- if not(fortlang!* memq '(fort c)) then
- typerr(fortlang!*,"target language");
- if not posintegerp card_no
- then typerr(card_no,"FORTRAN card number");
- if not posintegerp fort_width
- then typerr(fort_width,"FORTRAN line width");
- llength := linelength fort_width;
- if stringp u
- then return <<fprin2!* u;
- if w eq 'only then fterpri(t);
- linelength llength>>;
- if eqcar(u,'!*sq) then u := prepsq!* sqhorner!* cadr u;
- scountr := 0;
- nchars := if fortlang!* = 'c then 999999
- else ((linelength nil-spare!*)-12)*card_no;
- %12 is to allow for indentation and end of line effects;
- svar := varnam!*;
- fvar := if null v then (if fortlang!*='fort then svar else nil)
- else car v;
- if posn!*=0 and w then fortpri(fvar,u,w)
- else fortpri(nil,u,w);
- % should mean expression preceded by a string.
- linelength llength
- end;
- symbolic procedure fortpri(fvar,xexp,w);
- begin scalar fbrkt;
- if eqcar(xexp,'list)
- then <<posn!* := 0;
- fprin2!* "C ***** INVALID FORTRAN CONSTRUCT (";
- fprin2!* car xexp;
- return fprin2!* ") NOT PRINTED">>;
- if flength(xexp,nchars)<0
- then xexp := car xexp . fout(cdr xexp,car xexp,w);
- if fvar
- then <<posn!* := 0;
- fprin2!* " ";
- fmprint(fvar,0);
- fprin2!* "=">>;
- fmprint(xexp,0);
- if fortlang!*='fort and w or w='last then fterpri(w)
- end;
- symbolic procedure fout(args,op,w);
- begin integer ncharsl; scalar distop,x,z;
- ncharsl := nchars;
- if op memq '(plus times) then distop := op;
- while args do
- <<x := car args;
- if atom x and (ncharsl := flength(x,ncharsl))
- or (null cdr args or distop)
- and (ncharsl := flength(x,ncharsl))>0
- then z := x . z
- else if distop and flength(x,nchars)>0
- then <<z := fout1(distop . args,w) . z;
- args := list nil>>
- else <<z := fout1(x,w) . z;
- ncharsl := flength(op,ncharsl)>>;
- ncharsl := flength(op,ncharsl);
- args := cdr args>>;
- return reversip!* z
- end;
- symbolic procedure fout1(xexp,w);
- begin scalar fvar;
- fvar := genvar();
- explis := (xexp . fvar) . explis;
- fortpri(fvar,xexp,w);
- return fvar
- end;
- % If we are in a comment, we want to continue to stay in one,
- % Even if there's a formula. That's the purpose of this flag
- % Added by James Davenport after Francoise Richard.
- global '(comment!*);
- symbolic procedure fprin2!* u;
- % FORTRAN output of U.
- begin integer m,n;
- if posn!*=0 then comment!* :=
- stringp u and cadr(explode u) eq 'C;
- n := flatsizec u;
- m := posn!*+n;
- if fixp u and !*period then m := m+1;
- if m<(linelength nil-spare!*) then posn!* := m
- else <<terpri();
- if comment!* then << fprin2 "C"; spaces 4 >>
- else spaces 5;
- prin2 if fortlang!*='c then " " else ". ";
- posn!* := n+7>>;
- fprin2 u;
- if fixp u and !*period then prin2 "."
- end;
- symbolic procedure prin2!-downcase u;
- for each c in explode2 u do
- if liter c then prin2 red!-char!-downcase c else prin2 c;
- symbolic procedure prin2!-upcase u;
- for each c in explode2 u do
- if liter c then prin2 red!-char!-upcase c else prin2 c;
- symbolic procedure fprin2 u;
- % Prints id or string u so that case of all characters depends on
- % !*fortupper. Note !*lower setting only relevant here for PSL.
- (if !*fortupper then prin2!-upcase u else prin2!-downcase u)
- where !*lower = nil;
- symbolic procedure red!-char!-downcase u;
- (if x then cdr x else u) where x = atsoc(u,charassoc!*);
- symbolic procedure red!-char!-upcase u;
- (if x then car x else u) where x = rassoc(u,charassoc!*);
- symbolic procedure fterpri(u);
- <<if not(posn!*=0) and u then terpri();
- posn!* := 0>>;
- symbolic procedure genvar;
- intern compress append(explode svar,explode(scountr := scountr + 1));
- mkop 'no_period; % for printing of expressions with period locally off.
- put('no_period,'fort,'fo_no_period);
- symbolic procedure fo_no_period(u,p);
- begin scalar !*period; fmprint(cadr u,p) end;
- endmodule;
- end;
|