1 /* A nice test of the translator would be to translate the entire test suite ...
2 * In the meantime here are some tests to verify some specific bugs are fixed.
8 /* SF [ 1728888 ] translator bugs: no mnot mprogn */
10 (foo (e,v) := block([vi], for vi in v while not(emptyp(e)) do (print(vi), e : rest(e)), e),
11 foo ([1, 2, 3], [a, b]));
14 (translate (foo), ?funcall (foo, [1, 2, 3], [a, b]));
17 /* simpler function featuring mprogn and mnot */
19 (bar (x) := (x : 2*x, x : 3*x, not (x < 100)), bar (3));
22 (translate (bar), ?funcall (bar, 3));
25 /* SF [ 1646525 ] no function mdoin */
27 (try_me(x) := block([acc : 0], for i in x while i > 5 do acc : acc + i, acc),
28 try_me ([10, 9, 8, 7, 6, 5, 4, 5, 6, 7, 8, 9, 10]));
31 (translate (try_me), ?funcall (try_me, [10, 9, 8, 7, 6, 5, 4, 5, 6, 7, 8, 9, 10]));
34 /* SF [ 1818645 ] Compiled maxima code containing $ARRAY gets a Lisp error. */
36 (test_array_comp (x) :=
39 for i thru 3 do (abc[i]: i*i),
41 [abc, abc[3], abc[2]]),
42 test_array_comp (100));
45 (translate (test_array_comp), ?funcall (test_array_comp, 100));
48 /* SF [ 545794 ] Local Array does not compile properly */
54 for i : 0 thru 7 do myvar [i] : a^i,
55 [member (myvar, arrays), listarray (myvar)]),
57 [true, [1, 2, 4, 8, 16, 32, 64, 128]];
59 (translate (trial), ?funcall (trial, 2));
60 [true, [1, 2, 4, 8, 16, 32, 64, 128]];
62 /* Next test fails because local(myvar) in translated code doesn't clean up properties ... */
64 [member (myvar, arrays), errcatch (listarray (myvar))];
67 /* for loop variable not special
68 * reported to mailing list 2009-08-13 "Why won't this compile?"
73 baz1 (n) := block ([S : 0], for bar1:0 thru n - 1 do S : S + foo1 (), S),
78 /* original example */
80 (fun(A,b,s,VF,x,h):= block
84 Y[i]: x + h*(sum(A[i,j]*VF(Y[j]),j,1,i-1)),
85 x: expand(x + h*sum(b[i]*VF(Y[i]),i,1,s))),
86 A: matrix([1,1],[1,1]),
91 fun(A,b,2,f,[1,1],.01);
92 0.01*f(0.01*f([1,1])+[1,1])+0.01*f([1,1])+[1,1]$
94 (translate (fun), fun(A,b,2,f,[1,1],.01));
95 0.01*f(0.01*f([1,1])+[1,1])+0.01*f([1,1])+[1,1]$
97 /* incorrect code emitted for call from translated function to untranslated
98 * SF bug # 2934064 "problem loading ezunits"
101 (f0001 (x) := [f0002 (x), f0003 (x)],
104 translate (f0002, f0001),
108 (translate (f0003), f0001 (1));
111 (compile (f0003), f0001 (1));
114 (compile (f0003, f0002, f0001), f0001 (1));
117 /* SF bug # 2938716 "too much evaluation in translated code"
120 (g0001 (x) := [g0002 (x), g0003 (x)],
123 translate (g0002, g0001),
130 (translate (g0003), g0001 (aa));
133 (compile (g0003), g0001 (aa));
136 (compile (g0003, g0002, g0001), g0001 (aa));
139 /* SF bug # 3035313 "some array references translated incorrectly"
142 (kill (aa1, aa3, bb1, bb3, cc1, cc3),
144 array (aa3, 12, 4, 6),
145 array (bb1, flonum, 15),
146 array (bb3, flonum, 5, 6, 7),
147 array (cc1, fixnum, 8),
148 array (cc3, fixnum, 6, 10, 4),
152 (kill (faa, gaa, fbb, gbb, fcc, gcc),
153 faa (n) := aa1[n] + aa3[n, n - 1, n - 2],
154 gaa (n) := (aa1[n] : 123, aa3[n, n - 1, n - 2] : 321),
155 fbb (n) := bb1[n] + bb3[n, n - 1, n - 2],
156 gbb (n) := (bb1[n] : 123, bb3[n, n - 1, n - 2] : 321),
157 fcc (n) := cc1[n] + cc3[n, n - 1, n - 2],
158 gcc (n) := (cc1[n] : 123, cc3[n, n - 1, n - 2] : 321),
162 [gaa (4), gbb (4), gcc (4)];
165 [faa (4), fbb (4), fcc (4)];
168 translate (faa, gaa, fbb, gbb, fcc, gcc);
169 [faa, gaa, fbb, gbb, fcc, gcc];
171 [gaa (4), gbb (4), gcc (4)];
174 [faa (4), fbb (4), fcc (4)];
177 compile (faa, gaa, fbb, gbb, fcc, gcc);
178 [faa, gaa, fbb, gbb, fcc, gcc];
180 [gaa (4), gbb (4), gcc (4)];
183 [faa (4), fbb (4), fcc (4)];
186 /* try same stuff again w/ undeclared arrays ...
187 * no type spec => only one kind of array
190 (kill (aa1, aa3, bb1, bb3, cc1, cc3),
196 (translate (faa, gaa), [gaa (4), faa (4)]);
199 (compile (faa, gaa), [gaa (4), faa (4)]);
202 /* try same stuff again w/ Lisp arrays */
204 (kill (aa1, aa3, bb1, bb3, cc1, cc3),
205 map (?fmakunbound, [faa, fbb, fcc, gaa, gbb, gcc]),
206 aa1 : make_array (any, 15),
207 aa3 : make_array (any, 12, 4, 6),
208 bb1 : make_array (flonum, 15),
209 bb3 : make_array (flonum, 5, 6, 7),
210 cc1 : make_array (fixnum, 8),
211 cc3 : make_array (fixnum, 6, 10, 4),
215 [gaa (4), gbb (4), gcc (4)];
218 [faa (4), fbb (4), fcc (4)];
221 translate (faa, gaa, fbb, gbb, fcc, gcc);
222 [faa, gaa, fbb, gbb, fcc, gcc];
224 [gaa (4), gbb (4), gcc (4)];
227 [faa (4), fbb (4), fcc (4)];
230 compile (faa, gaa, fbb, gbb, fcc, gcc);
231 [faa, gaa, fbb, gbb, fcc, gcc];
233 [gaa (4), gbb (4), gcc (4)];
236 [faa (4), fbb (4), fcc (4)];
239 /* SF bug # 2569: "translate rat(1,x) and rat([1]) incorrect" */
241 (kill (f), f () := rat (x, x), translate (f), f ());
244 (kill (f), f () := rat ([1]), translate (f), f ());
247 (kill (foo, y1a, y1b, y2a, y2b),
248 foo(x) := block (mode_declare (x, float),
249 [tanh (x), tan (x), sech (x), sec (x), acos (x), acot (x), sin (x),
250 acsc (x), asinh (x), acsch (x), cosh (x), coth (x), realpart (x),
251 asec (x), asin (x), erf (x), log (x), cos (x), cot (x), csc (x),
252 sinh (x), csch (x)]),
257 [.4621171572600097,.5463024898437905,0.886818883970074,1.139493927324549,
258 1.047197551196597,1.107148717794091,0.479425538604203,
259 1.570796326794897-1.316957896924817*%i,.4812118250596035,1.44363547517881,
260 1.127625965206381,2.163953413738653,0.5,1.316957896924817*%i,
261 0.523598775598299,.5204998778130465,-.6931471805599453,.8775825618903728,
262 1.830487721712452,2.085829642933488,.5210953054937474,1.919034751334944]$
265 [.9051482536448664,14.10141994717172,.4250960349422805,14.1368329029699,
266 .9624236501192069*%i,.5880026035475675,.9974949866040544,.7297276562269662,
267 1.194763217287109,.6251451172504168,2.352409615243247,1.104791392982512,1.5,
268 .8410686705679303,1.570796326794897-.9624236501192069*%i,.9661051464753108,
269 .4054651081081644,0.0707372016677029,.07091484430265245,1.002511304246725,
270 2.129279455094817,.4696424405952246]$
272 (translate (foo), y2a : foo (0.5), y2b : foo (1.5), 0);
281 /* verify that save/compfile/compile_file/translate_file preserves upper/lower case in symbol names */
286 foo (x) := my_foo * x,
287 Foo (x) := my_Foo * x,
288 FOO (x) := my_FOO * x,
289 [my_foo, my_Foo, my_FOO] : [123, 456, 789],
290 results : [foo (2), Foo (3), FOO (4)],
291 my_test () := is (results = [2*123, 3*456, 4*789]),
292 lisp_name : ssubst ("_", " ", build_info()@lisp_name),
293 lisp_filename : sconcat (maxima_tempdir, "/tmp-rtest_translator-save-", lisp_name, ".lisp"),
294 save (lisp_filename, values, functions),
295 kill (allbut (lisp_filename)),
296 load (lisp_filename),
303 foo (x) := my_foo * x,
304 Foo (x) := my_Foo * x,
305 FOO (x) := my_FOO * x,
306 lisp_name : ssubst ("_", " ", build_info()@lisp_name),
307 lisp_filename : sconcat (maxima_tempdir, "/tmp-rtest_translator-compfile-", lisp_name, ".lisp"),
308 compfile (lisp_filename, functions),
310 load (lisp_filename),
311 [my_foo, my_Foo, my_FOO] : [123, 456, 789],
312 results : [foo (2), Foo (3), FOO (4)],
313 my_test () := is (results = [2*123, 3*456, 4*789]),
319 /* skip this test (and fail) if Lisp = ECL because stream i/o causes "stack smashing" error
320 * see: https://sourceforge.net/p/maxima/bugs/3291/
322 if build_info()@lisp_name # "ECL" then
324 lisp_name : ssubst ("_", " ", build_info()@lisp_name),
325 maxima_filename : sconcat (maxima_tempdir, "/tmp-rtest_translator-compile_file-", lisp_name, ".mac"),
326 fasl_filename : sconcat (maxima_tempdir, "/tmp-rtest_translator-compile_file-", lisp_name, ".fasl"),
327 lisp_filename : sconcat (maxima_tempdir, "/tmp-rtest_translator-compile_file-", lisp_name, ".LISP"),
328 maxima_output : openw (maxima_filename),
330 "foo (x) := my_foo * x;
331 Foo (x) := my_Foo * x;
332 FOO (x) := my_FOO * x;
333 [my_foo, my_Foo, my_FOO] : [123, 456, 789];
334 results : [foo (2), Foo (3), FOO (4)];
335 my_test () := is (results = [2*123, 3*456, 4*789]);",
336 printf (maxima_output, maxima_content),
337 close (maxima_output),
338 compile_file (maxima_filename, fasl_filename, lisp_filename),
339 kill (allbut (lisp_filename)),
340 load (lisp_filename),
346 /* skip this test (and fail) if Lisp = ECL because stream i/o causes "stack smashing" error
347 * see: https://sourceforge.net/p/maxima/bugs/3291/
349 if build_info()@lisp_name # "ECL" then
351 lisp_name : ssubst ("_", " ", build_info()@lisp_name),
352 maxima_filename : sconcat (maxima_tempdir, "/tmp-rtest_translator-translate_file-", lisp_name, ".mac"),
353 lisp_filename : sconcat (maxima_tempdir, "/tmp-rtest_translator-translate_file-", lisp_name, ".LISP"),
354 maxima_output : openw (maxima_filename),
356 "foo (x) := my_foo * x;
357 Foo (x) := my_Foo * x;
358 FOO (x) := my_FOO * x;
359 [my_foo, my_Foo, my_FOO] : [123, 456, 789];
360 results : [foo (2), Foo (3), FOO (4)];
361 my_test () := is (results = [2*123, 3*456, 4*789]);",
362 printf (maxima_output, maxima_content),
363 close (maxima_output),
364 translate_file (maxima_filename, lisp_filename),
365 kill (allbut (lisp_filename)),
366 load (lisp_filename),
372 Translating a literal exponent that comes out as a float shouldn't
373 produce assigned type any. This test runs the translation for a
374 trivial function that triggered the bug then looks in the unlisp
375 file (which contains messages from the translator) and checks that
376 there aren't any warnings.
378 /* skip this test (and fail) if Lisp = ECL because stream i/o causes "stack smashing" error
379 * see: https://sourceforge.net/p/maxima/bugs/3291/
381 if build_info()@lisp_name # "ECL" then
383 lisp_name : ssubst ("_", " ", build_info()@lisp_name),
384 basename: sconcat (maxima_tempdir, "/tmp-rtest_translator-2934-", lisp_name),
385 maxima_filename : sconcat (basename, ".mac"),
386 lisp_filename : sconcat (basename, ".LISP"),
387 maxima_output : openw (maxima_filename),
388 maxima_content : "f () := block([y], mode_declare(y,float), y: 3^0.33, y)$",
389 printf (maxima_output, maxima_content),
390 close (maxima_output),
391 translate_file (maxima_filename, lisp_filename),
392 kill (allbut(basename)),
393 /* Any warning messages end up at .UNLISP */
394 block ([unlisp: openr (sconcat (basename, ".UNLISP")),
396 while stringp (line: readline(unlisp)) do
397 if is ("warning" = split(line, ":")[1]) then push(line, acc),
401 /* makelist translated incorrectly
402 * SF bug #3083: "Error on compiling a working maxima function"
406 f1(n) := makelist (1, n),
407 f2(n) := makelist (i^2, i, n),
408 f3(l) := makelist (i^3, i, l),
409 f4(n) := makelist (i^4, i, 1, n),
410 f5(m, n) := makelist (i^5, i, 1, n, m),
411 translate(f1, f2, f3, f4, f5),
428 [1, 243, 3125, 16807, 59049];
430 /* original function from bug report */
432 (ordersort(lis,vars,oper):=block([negsumdispflag:false,liss:lis,varlist:vars,temp], /*Does lexicographical sort */
433 for i:1 thru length(varlist) do (
435 liss:sort(liss,lambda([x,y],apply("and",map(oper,makelist(part(x,2)[k],k,1,i)
436 ,makelist(part(y,2)[k],k,1,i)))))
438 translate (ordersort)); /* 'translate' doesn't trigger an error, so check return value */
441 [member ('transfun, properties(ordersort)),
442 ordersort([[-7,[0,2,1]],[3,[1,2,1]],[1,[0,4,1]],[6,[4,3,3]],[6,[4,4,3]],[-7,[3,5,4]],[2,[0,0,5]],[-10,[2,2,5]],[-10,[3,4,7]],[7,[3,8,9]]],[x,y,z],">=")];
443 [true, [[6,[4,4,3]],[6,[4,3,3]],[7,[3,8,9]],[-7,[3,5,4]],[-10,[3,4,7]],[-10,[2,2,5]],[3,[1,2,1]],[1,[0,4,1]],[-7,[0,2,1]],[2,[0,0,5]]]];
445 /* 'define' translated incorrectly, reported to mailing list circa 2017-01-24 */
447 (kill(foo, bar, baz, quux, mumble, blurf, umm, f, x, y),
448 foo(y) := define(bar(x), x + y),
449 baz(f, y) := define(funmake(f, [x]), x + y),
450 quux() := (mumble(x) := 1 + x),
451 [foo(10), baz(blurf, 20), quux()]);
452 /* note that results match because rhs of ":=" isn't simplified */
453 [bar(x) := 10 + x, blurf(x) := 20 + x, mumble(x) := 1 + x];
455 [bar(5), blurf(5), mumble(5)];
458 (kill(bar, blurf, mumble),
459 translate(foo, baz, quux),
460 [foo(11), baz(umm, 21), quux()]);
461 /* note that results match because rhs of ":=" isn't simplified */
462 [bar(x) := 11 + x, umm(x) := 21 + x, mumble(x) := 1 + x];
464 map (?fboundp, [foo, baz, quux]);
467 [bar(5), umm(5), mumble(5)];
470 /* mailing list 2017-03-04: "An example that is broken by compile()"
471 * translated code tickles a bug elsewhere (bug not in translator)
474 (kill(fun, trigfunc, t1),
475 fun():=block([trigfunc],
476 trigfunc:lambda([cur],cur>t1),
477 apply('trigfunc,[1])),
481 /* I (Robert Dodier) believe this result should be trigfunc(1),
482 * but, in any event, interpreted and compiled code should agree.
483 * But if MAPPLY1 is ever changed, we can adjust these results.
488 (compile(fun), fun());
491 (kill(fun, trigfunc, t1),
492 fun():=block([trigfunc],
493 trigfunc:lambda([cur],cur>t1),
494 apply(trigfunc,[1])),
501 (compile(fun), fun());
504 /* Verify that we catch malformed lambda expressions during translation.
505 * More checks need to be added to the translator and more tests need to
509 /* no parameter list */
517 f () := lambda ([x]),
521 /* non-symbol in parameter list */
523 f () := lambda ([42], 'foo),
527 /* misplaced "rest" parameter */
529 f () := lambda ([[l], x], 'foo),
533 /* invalid "rest" parameter */
535 f () := lambda ([[l1, l2]], 'foo),
539 /* attempting to bind a constant;
540 * now OK, after commit 0517895
544 declare (c, constant),
545 f () := lambda ([c], c),
549 /* Verify that parameter/variable lists cannot contain duplicate variables.
551 * We only test a couple of cases here. Many more tests for non-translated
552 * code are in rtest2. Do we want to test them all here as well?
556 f () := lambda ([x, [x]], x),
561 f () := block ([x, x:'foo], x),
565 /* ensure that a null OPERATORS property doesn't interfere with
566 * translation of local variable used as a function name.
567 * This is the bug that caused failures in rtest_fractals when executed after run_testsuite.
570 (kill(aa, foobarbaz, mumbleblurf, hhh),
571 matchdeclare (aa, all),
572 tellsimp (mumbleblurf(aa), 1 - aa),
573 kill (mumbleblurf), /* as of 2018-01-28, this leaves (OPERATORS NIL) in property list */
574 hhh(mumbleblurf, u) := mumbleblurf(u),
575 foobarbaz(x) := 100 + x,
577 hhh (foobarbaz, 11));
580 /* SF bug report #3402: "Unbinding defined variable generates error in compiled functions" */
582 define_variable (zorble, 0, fixnum);
585 (kill(f), f() := block ([zorble], 42), f());
594 /* bug reported to mailing list 2018-12-03: "error in compiling function with global variable" */
596 (test_f():= block( [a,b,c,d], niceindicespref:[a,b,c,d], disp("ciao"), return() ),
600 (test_f (), niceindicespref);
603 (reset (niceindicespref),
612 (reset (niceindicespref), 0);
615 /* additional tests with variables which have ASSIGN property */
617 (set_error_stuff_permanently () :=
618 block (error_syms : '[myerr1, myerr2, myerr3], error_size : 40),
619 set_error_stuff_temporarily() :=
620 block([error_syms : '[myerror1, myerror2, myerror3], error_size : 55],
621 [error_syms, error_size]),
625 (reset (error_syms, error_size),
626 set_error_stuff_permanently (),
627 [error_syms, error_size]);
628 [[myerr1, myerr2, myerr3], 40];
630 (reset (error_syms, error_size),
631 translate (set_error_stuff_permanently),
632 set_error_stuff_permanently (),
633 [error_syms, error_size]);
634 [[myerr1, myerr2, myerr3], 40];
636 (reset (error_syms, error_size),
637 set_error_stuff_temporarily());
638 [[myerror1, myerror2, myerror3], 55];
640 [error_syms, error_size];
641 [[errexp1, errexp2, errexp3], 60];
643 (translate (set_error_stuff_temporarily),
644 set_error_stuff_temporarily());
645 [[myerror1, myerror2, myerror3], 55];
647 [error_syms, error_size];
648 [[errexp1, errexp2, errexp3], 60];