2 /* Generation of FORTRAN Code
3 Using Macsyma's GENTRAN Package
8 1. Translation of Basic Program Statements from Macsyma to FORTRAN */
9 (genfloat : true, gentranlang : 'fortran)$
11 /* 1.1 Translate assignment statements. */
12 gentran( p : a*x^2+b*x+c )$
14 /* C:\MACSYMA2\library2\gentran.fas being loaded.
17 /* 1.2 Translate matrix structures. */
18 gentran( m : matrix([u,2*u^2],[-v^2,v]) )$
25 /* 1.3 Translate iteration loops.
27 Gentran keeps track of statement labels, to assure uniqueness. */
28 gentran( for i step 2 thru 9 do
35 /* Iteration loops with "next" */
36 gentran( for n from 2 next n*2 thru 500 do
40 25002 IF (N.GT.500.0d0) GOTO 25003
46 /* Iteration loops with "while" */
47 gentran( while f(x) >= 0 do x : x+0.25 )$
49 /* 25004 IF (.NOT.F(X).GE.0.0d0) GOTO 25005
54 /* Iteration loops with "unless" */
55 gentran( unless f(x) >= 0 do x : x+0.25 )$
57 /* 25006 IF (F(X).GE.0.0d0) GOTO 25007
62 /* 1.4 Translate conditional branching "if-then" statements. */
63 gentran( if x > 0 then y : x )$
65 /* IF (.NOT.X.GT.0.0d0) GOTO 25008
69 /* "If-then-else" statements */
70 gentran (if x > 0 then y : x else y : -x )$
72 /* IF (.NOT.X.GT.0.0d0) GOTO 25009
79 /* 1.5 Translate function calls. */
80 gentran( calcv(v,x,y,z) )$
82 /* CALL CALCV(V,X,Y,Z) */
84 /* 1.6 Translate Macsyma Programs.
86 Translate compound statements. */
87 gentran( (u1 : x^2, u2 : x-y) )$
92 /* Translate Macsyma program blocks. */
93 gentran( block(u1 : x^2,u2 : x-y) )$
98 /* Translate statement labels and explicit "go" statements. */
99 gentran( block(f : 1, i : 1,
102 if i <= n then go(loop)) )$
109 IF (.NOT.I.LE.N) GOTO 25012
113 /* Translate function definitions into function definitions. */
114 gentran( f(a,b,c,x) := block(z : a*b*c+x, return(z)) )$
116 /* FUNCTION F(A,B,C,X)
122 /* Translate function definitions into subroutine definitions. */
123 gentran( f(a,b,c,x) := block(z : a*b*c+x, print("z = ",z)) )$
125 /* SUBROUTINE F(A,B,C,X)
131 /* 1.7 Control evaluation during translation. */
134 (Use the expression F in the following examples.) */
137 /* Control evaluation of symbols and operations. */
138 gentran( q : eval(f)/eval(diff(f,x)) )$
140 /* Q=(3.0d0*X**2-(8.0d0*X)+4.0d0)/(6.0d0*X-8.0d0) */
142 /* Tell Gentran to evaluate only the RHS of an assignment statement. */
143 gentran( rsetq(deriv, diff(a*x^4-4*b*x^3+3*c*x^2/2,x)) )$
145 /* DERIV=4.0d0*A*X**3-(12.0d0*B*X**2)+3.0d0*C*X */
147 /* Tell Gentran to evaluate only the LHS of an assignment statement. */
149 gentran ( lsetq(m(j,j),0) )$
155 m : matrix([a,0,-1], [a^2,b,a/b], [b^2,0,c]);
157 /* Tell Gentran to evaluate both the left and right sides of an assignment statement. */
159 gentran( lrsetq(m[j,j], m[j,j]) )$
165 /* 1.8 Translate comments and other literal strings. */
166 gentran ( for i thru n do
167 literal("C",tab,"THIS IS A FORTRAN COMMENT",cr,
168 tab,"WRITE(6,10) (M(I,J),J=1,N)",cr,
169 10,tab,"FORMAT(1X,10(I5,3X))",cr) )$
173 C THIS IS A FORTRAN COMMENT
174 WRITE(6,10) (M(I,J),J=1,N)
175 10 FORMAT(1X,10(I5,3X))
178 /* Clean up after the previous section. */
182 2. Automatic Expression Segmentation and Optimization */
185 2.1 Automatic Expression Segmentation */
188 First, translate with segmentation and optimization turned off. */
189 (gentranseg : false, gentranopt : false)$
191 /* We shall use this rather large expression in our examples. */
192 x : expand(a^6+(a+b)^6+(a+b+c)^6);
194 /* With segmentation turned off, Gentran reproduces large statements. */
195 gentran(x : eval(x))$
197 /* X=C**6+6.0d0*B*C**5+6.0d0*A*C**5+15.0d0*B**2*C**4+30.0d0*A*B*C**4+
198 . 15.0d0*A**2*C**4+20.0d0*B**3*C**3+60.0d0*A*B**2*C**3+60.0d0*A**2*
199 . B*C**3+20.0d0*A**3*C**3+15.0d0*B**4*C**2+60.0d0*A*B**3*C**2+
200 . 90.0d0*A**2*B**2*C**2+60.0d0*A**3*B*C**2+15.0d0*A**4*C**2+6.0d0*B
201 . **5*C+30.0d0*A*B**4*C+60.0d0*A**2*B**3*C+60.0d0*A**3*B**2*C+
202 . 30.0d0*A**4*B*C+6.0d0*A**5*C+2.0d0*B**6+12.0d0*A*B**5+30.0d0*A**2
203 . *B**4+40.0d0*A**3*B**3+30.0d0*A**4*B**2+12.0d0*A**5*B+3.0d0*A**6 */
205 /* Turn on segmentation, and set maximum expression length to 100 characters. */
206 (gentranseg : true, maxexpprintlen : 100)$
208 /* With segmentation turned on, Gentran breaks up large expressions into several statements. It introduces uniquely named
209 dummy variables in this process. */
210 gentran(x : eval(x))$
212 /* T0=C**6+6.0d0*B*C**5+6.0d0*A*C**5+15.0d0*B**2*C**4+30.0d0*A*B*C**4
214 T0=T0+20.0d0*B**3*C**3+60.0d0*A*B**2*C**3+60.0d0*A**2*B*C**3+
216 T0=T0+15.0d0*B**4*C**2+60.0d0*A*B**3*C**2+90.0d0*A**2*B**2*C**2+
218 T0=T0+15.0d0*A**4*C**2+6.0d0*B**5*C+30.0d0*A*B**4*C+60.0d0*A**2*B
220 T0=T0+60.0d0*A**3*B**2*C+30.0d0*A**4*B*C+6.0d0*A**5*C+2.0d0*B**6+
222 X=T0+30.0d0*A**2*B**4+40.0d0*A**3*B**3+30.0d0*A**4*B**2+12.0d0*A**
225 /* 2.2 Automatic Expression Optimization
227 Translate with segmentation turned of and automatic expression optimization on. */
228 (gentranseg : false, gentranopt : true)$
230 /* When optimization is turned on, Gentran identifies common subexpressions and defines variables for them. */
231 gentran( x : eval(x) )$
233 /* C:\MACSYMA2\library1\optim.fas being loaded.
246 X=C**6+6.0d0*B*U11+6.0d0*A*U11+15.0d0*U2*U10+30.0d0*A*B*U10+15.0d0
247 . *U5*U10+20.0d0*U4*U9+60.0d0*A*U2*U9+60.0d0*U5*B*U9+20.0d0*U3*U9+
248 . 15.0d0*U6*U8+60.0d0*A*U4*U8+90.0d0*U5*U2*U8+60.0d0*U3*B*U8+15.0d0
249 . *U1*U8+6.0d0*U7*C+30.0d0*A*U6*C+60.0d0*U5*U4*C+60.0d0*U3*U2*C+
250 . 30.0d0*U1*B*C+6.0d0*U0*C+2.0d0*B**6+12.0d0*A*U7+30.0d0*U5*U6+
251 . 40.0d0*U3*U4+30.0d0*U1*U2+12.0d0*U0*B+3.0d0*A**6 */
253 /* Clean up after previous section. */
254 (remvalue(x), gentranopt : false, maxexpprintlen : 800)$
257 3. Type Declarations for Functions and Variables */
260 3.1 Explicit Type Declarations
262 Gentran translates this function into a FORTRAN integer-valued function with integer argument N. Gentran figures out that
263 the internal variables F and I must be type integer. */
265 block(type(function,fac),
269 f : f*i,type(integer,f,i),
273 INTEGER FUNCTION FAC(N)
283 /* 3.2 Implicit Type Declarations
285 Gentran will declare the types generated dummy variables when this can be determined from the context, or it will declare
286 them to be the type you specify as the value of TEMPVARTYPE. */
287 (gentranseg : true, maxexpprintlen : 15, tempvartype : 'real)$
288 gentran( type(integer, i),
290 x : x1+x2+x3+x4+x5+x6,
291 i : i1*i2*i3*i4*i5*i6,
292 y : y1-y2+y3-y4+y5-y6,
293 z : z1*z2*z3+z4*z5*z6 )$
310 4. Generation and Marking of Temporary Variables.
312 (tempvartype : false, maxexpprintlen : 800, gentranseg : false)$
314 /* You can generate a numbered "temporary variable" using the command tempvar. */
315 varname : tempvar(false);
317 /* Invoking tempvar again generates the same variable name. */
320 /* You can mark a variable name as used with the command markvar . . . */
323 /* . . . after which another invocation of tempvar returns a new variable name. */
326 /* You can unmark a variable name . . . */
329 /* . . . and generate the name again. */
331 m : matrix([a*(b+c),0,a*c],[-a,a-b,0],[a*c,0,c^2]);
333 /* Here is an example using tempvar and markvar. */
337 var : tempvar(false),
339 gentran( eval(var) : eval(m[i,j]) ),
351 /* Clean up after previous section. */