1 package uk.co.codemist.jlisp.core;
2 
3 //
4 // This file is part of the Jlisp implementation of Standard Lisp
5 // Copyright \u00a9 (C) Codemist Ltd, 1998-2015.
6 //
7 
8 // Fns2.java
9 
10 /**************************************************************************
11  * Copyright (C) 1998-2015, Codemist Ltd.                A C Norman       *
12  *                            also contributions from Vijay Chauhan, 2002 *
13  *                                                                        *
14  * Redistribution and use in source and binary forms, with or without     *
15  * modification, are permitted provided that the following conditions are *
16  * met:                                                                   *
17  *                                                                        *
18  *     * Redistributions of source code must retain the relevant          *
19  *       copyright notice, this list of conditions and the following      *
20  *       disclaimer.                                                      *
21  *     * Redistributions in binary form must reproduce the above          *
22  *       copyright notice, this list of conditions and the following      *
23  *       disclaimer in the documentation and/or other materials provided  *
24  *       with the distribution.                                           *
25  *                                                                        *
26  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS    *
27  * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT      *
28  * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS      *
29  * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE         *
30  * COPYRIGHT OWNERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,   *
31  * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,   *
32  * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS  *
33  * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND *
34  * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR  *
35  * TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF     *
36  * THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH   *
37  * DAMAGE.                                                                *
38  *************************************************************************/
39 // This is a whole load of support for the numeric data-types
40 
41 // To do:  iplus etc
42 //         modular-plus etc
43 //         fix/float/round/ceiling
44 //         hyperbolic functions
45 
46 import java.io.*;
47 import java.util.*;
48 import java.text.*;
49 import java.math.*;
50 
51 class Fns2
52 {
53     Object [][] builtins =
54     {
55         {"abs",                         new AbsFn()},
56         {"acos",                        new AcosFn()},
57         {"acosd",                       new AcosdFn()},
58         {"acosh",                       new AcoshFn()},
59         {"acot",                        new AcotFn()},
60         {"acotd",                       new AcotdFn()},
61         {"acoth",                       new AcothFn()},
62         {"acsc",                        new AcscFn()},
63         {"acscd",                       new AcscdFn()},
64         {"acsch",                       new AcschFn()},
65         {"add1",                        new Add1Fn()},
66         {"asec",                        new AsecFn()},
67         {"asecd",                       new AsecdFn()},
68         {"asech",                       new AsechFn()},
69         {"ash",                         new AshFn()},
70         {"ash1",                        new Ash1Fn()},
71         {"asin",                        new AsinFn()},
72         {"asind",                       new AsindFn()},
73         {"asinh",                       new AsinhFn()},
74         {"atan",                        new AtanFn()},
75         {"atan2",                       new Atan2Fn()},
76         {"atan2d",                      new Atan2dFn()},
77         {"atand",                       new AtandFn()},
78         {"atanh",                       new AtanhFn()},
79         {"ceiling",                     new CeilingFn()},
80         {"cos",                         new CosFn()},
81         {"cosd",                        new CosdFn()},
82         {"cosh",                        new CoshFn()},
83         {"cot",                         new CotFn()},
84         {"cotd",                        new CotdFn()},
85         {"coth",                        new CothFn()},
86         {"csc",                         new CscFn()},
87         {"cscd",                        new CscdFn()},
88         {"csch",                        new CschFn()},
89         {"difference",                  new DifferenceFn()},
90         {"divide",                      new DivideFn()},
91         {"eq-safe",                     new EqSafeFn()},
92         {"eqn",                         new EqnFn()},
93         {"evenp",                       new EvenpFn()},
94         {"exp",                         new ExpFn()},
95         {"expt",                        new ExptFn()},
96         {"find-gnuplot",                new FindGnuplotFn()},
97         {"fix",                         new FixFn()},
98         {"fixp",                        new FixpFn()},
99         {"float",                       new FloatFn()},
100         {"floatp",                      new FloatpFn()},
101         {"floor",                       new FloorFn()},
102         {"frexp",                       new FrexpFn()},
103         {"gcdn",                        new GcdnFn()},
104         {"geq",                         new GeqFn()},
105         {"greaterp",                    new GreaterpFn()},
106         {"hypot",                       new HypotFn()},
107         {"iadd1",                       new Iadd1Fn()},
108         {"id2string",                   new Id2stringFn()},
109         {"idifference",                 new IdifferenceFn()},
110         {"igeq",                        new IgeqFn()},
111         {"igreaterp",                   new IgreaterpFn()},
112         {"ileq",                        new IleqFn()},
113         {"ilessp",                      new IlesspFn()},
114         {"ilogand",                     new IlogandFn()},
115         {"ilogor",                      new IlogorFn()},
116         {"ilogxor",                     new IlogxorFn()},
117         {"imax",                        new ImaxFn()},
118         {"imin",                        new IminFn()},
119         {"iminus",                      new IminusFn()},
120         {"iminusp",                     new IminuspFn()},
121         {"integerp",                    new IntegerpFn()},
122         {"ionep",                       new IonepFn()},
123         {"iplus",                       new IplusFn()},
124         {"iplus2",                      new Iplus2Fn()},
125         {"iquotient",                   new IquotientFn()},
126         {"iremainder",                  new IremainderFn()},
127         {"ashift",                      new AshiftFn()},
128         {"lshift",                      new LshiftFn()},
129         {"irightshift",                 new IrightshiftFn()},
130         {"is-spid",                     new Is_spidFn()},
131         {"spid-to-nil",                 new Spid_to_nilFn()},
132         {"isub1",                       new Isub1Fn()},
133         {"itimes",                      new ItimesFn()},
134         {"itimes2",                     new Itimes2Fn()},
135         {"izerop",                      new IzeropFn()},
136         {"lcm",                         new LcmnFn()},
137         {"lcmn",                        new LcmnFn()},
138         {"leq",                         new LeqFn()},
139         {"lessp",                       new LesspFn()},
140         {"ln",                          new LnFn()},
141         {"log",                         new LogFn()},
142         {"log10",                       new Log10Fn()},
143         {"land",                        new LogandFn()},
144         {"logand",                      new LogandFn()},
145         {"logb",                        new LogbFn()},
146         {"logeqv",                      new LogeqvFn()},
147         {"lognot",                      new LognotFn()},
148         {"lor",                         new LogorFn()},
149         {"logor",                       new LogorFn()},
150         {"logxor",                      new LogxorFn()},
151         {"lose-precision",              new Lose_precisionFn()},
152         {"lsd",                         new LsdFn()},
153         {"max",                         new MaxFn()},
154         {"max2",                        new Max2Fn()},
155         {"min",                         new MinFn()},
156         {"min2",                        new Min2Fn()},
157         {"minus",                       new MinusFn()},
158         {"minusp",                      new MinuspFn()},
159         {"mod",                         new ModFn()},
160         {"modular-difference",          new Modular_differenceFn()},
161         {"modular-expt",                new Modular_exptFn()},
162         {"modular-minus",               new Modular_minusFn()},
163         {"modular-number",              new Modular_numberFn()},
164         {"modular-plus",                new Modular_plusFn()},
165         {"modular-quotient",            new Modular_quotientFn()},
166         {"modular-reciprocal",          new Modular_reciprocalFn()},
167         {"safe-modular-reciprocal",     new Safe_modular_reciprocalFn()},
168         {"modular-times",               new Modular_timesFn()},
169         {"msd",                         new MsdFn()},
170         {"mv-list",                     new MvListFn()},
171         {"numberp",                     new NumberpFn()},
172         {"oddp",                        new OddpFn()},
173         {"onep",                        new OnepFn()},
174         {"plus",                        new PlusFn()},
175         {"plus2",                       new Plus2Fn()},
176         {"plusp",                       new PluspFn()},
177         {"quotient",                    new QuotientFn()},
178         {"random-fixnum",               new Random_fixnumFn()},
179         {"random",                      new Random_numberFn()},
180         {"random-number",               new Random_numberFn()},
181         {"rational",                    new RationalFn()},
182         {"remainder",                   new RemainderFn()},
183         {"round",                       new RoundFn()},
184         {"sec",                         new SecFn()},
185         {"secd",                        new SecdFn()},
186         {"sech",                        new SechFn()},
187         {"set-small-modulus",           new Set_small_modulusFn()},
188         {"sin",                         new SinFn()},
189         {"sind",                        new SindFn()},
190         {"sinh",                        new SinhFn()},
191         {"sqrt",                        new SqrtFn()},
192         {"sub1",                        new Sub1Fn()},
193         {"tan",                         new TanFn()},
194         {"tand",                        new TandFn()},
195         {"tanh",                        new TanhFn()},
196         {"times",                       new TimesFn()},
197         {"times2",                      new Times2Fn()},
198         {"truncate",                    new TruncateFn()},
199         {"zerop",                       new ZeropFn()}
200     };
201 
202 
203 
204 class Plus2Fn extends BuiltinFunction
205 {
op2(LispObject arg1, LispObject arg2)206     public LispObject op2(LispObject arg1, LispObject arg2) throws Exception
207     {
208         return arg1.add(arg2);
209     }
210 }
211 
212 
213 
214 class PlusFn extends BuiltinFunction
215 {
op0()216     public LispObject op0() { return LispInteger.valueOf(0); }
op1(LispObject arg1)217     public LispObject op1(LispObject arg1) { return arg1; }
op2(LispObject arg1, LispObject arg2)218     public LispObject op2(LispObject arg1, LispObject arg2) throws Exception
219     {
220         return arg1.add(arg2);
221     }
opn(LispObject [] args)222     public LispObject opn(LispObject [] args) throws Exception
223     {
224         LispObject r = args[0];
225         for (int i=1; i<args.length; i++)
226             r = r.add(args[i]);
227         return r;
228     }
229 }
230 
231 class Times2Fn extends BuiltinFunction
232 {
op2(LispObject arg1, LispObject arg2)233     public LispObject op2(LispObject arg1, LispObject arg2) throws Exception
234     {
235         return arg1.multiply(arg2);
236     }
237 }
238 
239 
240 
241 class TimesFn extends BuiltinFunction
242 {
op0()243     public LispObject op0() { return LispInteger.valueOf(1); }
op1(LispObject arg1)244     public LispObject op1(LispObject arg1) { return arg1; }
op2(LispObject arg1, LispObject arg2)245     public LispObject op2(LispObject arg1, LispObject arg2) throws Exception
246     {
247         return arg1.multiply(arg2);
248     }
opn(LispObject [] args)249     public LispObject opn(LispObject [] args) throws Exception
250     {
251         LispObject r = args[0];
252         for (int i=1; i<args.length; i++)
253             r = r.multiply(args[i]);
254         return r;
255     }
256 }
257 
258 class Max2Fn extends BuiltinFunction
259 {
op2(LispObject arg1, LispObject arg2)260     public LispObject op2(LispObject arg1, LispObject arg2) throws Exception
261     {
262         return arg1.max(arg2);
263     }
264 }
265 
266 
267 
268 class MaxFn extends BuiltinFunction
269 {
op1(LispObject arg1)270     public LispObject op1(LispObject arg1) { return arg1; }
op2(LispObject arg1, LispObject arg2)271     public LispObject op2(LispObject arg1, LispObject arg2) throws Exception
272     {
273         return arg1.max(arg2);
274     }
opn(LispObject [] args)275     public LispObject opn(LispObject [] args) throws Exception
276     {
277         LispObject r = args[0];
278         for (int i=1; i<args.length; i++)
279             r = r.max(args[i]);
280         return r;
281     }
282 }
283 
284 class Min2Fn extends BuiltinFunction
285 {
op2(LispObject arg1, LispObject arg2)286     public LispObject op2(LispObject arg1, LispObject arg2) throws Exception
287     {
288         return arg1.min(arg2);
289     }
290 }
291 
292 
293 
294 class MinFn extends BuiltinFunction
295 {
op1(LispObject arg1)296     public LispObject op1(LispObject arg1) { return arg1; }
op2(LispObject arg1, LispObject arg2)297     public LispObject op2(LispObject arg1, LispObject arg2) throws Exception
298     {
299         return arg1.min(arg2);
300     }
opn(LispObject [] args)301     public LispObject opn(LispObject [] args) throws Exception
302     {
303         LispObject r = args[0];
304         for (int i=1; i<args.length; i++)
305             r = r.min(args[i]);
306         return r;
307     }
308 }
309 
310 class AbsFn extends BuiltinFunction
311 {
op1(LispObject arg1)312     public LispObject op1(LispObject arg1) throws Exception
313     {
314         return arg1.abs();
315     }
316 }
317 
318 class AcosFn extends BuiltinFunction
319 {
op1(LispObject arg1)320     public LispObject op1(LispObject arg1) throws Exception
321     {
322         double a = arg1.doubleValue();
323 	if (a > 1.0 || a < -1.0) return error("bad arg for acos");
324         a = Math.acos(a);
325         return new LispFloat(a);
326     }
327 }
328 
329 class AcosdFn extends BuiltinFunction
330 {
op1(LispObject arg1)331     public LispObject op1(LispObject arg1) throws Exception
332     {
333         double a = arg1.doubleValue();
334 	if (a > 1.0 || a < -1.0) return error("bad arg for acosd");
335         a = 180.0*Math.acos(a)/Math.PI;
336         return new LispFloat(a);
337     }
338 }
339 
340 class AcoshFn extends BuiltinFunction
341 {
op1(LispObject arg1)342     public LispObject op1(LispObject arg1) throws Exception
343     {
344         double a = arg1.doubleValue();
345 	if (a < 1.0) return error("bad arg for acosh");
346         a = MyMath.acosh(a);
347         return new LispFloat(a);
348     }
349 }
350 
351 class AcotFn extends BuiltinFunction
352 {
op1(LispObject arg1)353     public LispObject op1(LispObject arg1) throws Exception
354     {
355         double a = arg1.doubleValue();
356         a = Math.PI/2.0 - Math.atan(a);
357         return new LispFloat(a);
358     }
359 }
360 
361 class AcotdFn extends BuiltinFunction
362 {
op1(LispObject arg1)363     public LispObject op1(LispObject arg1) throws Exception
364     {
365         double a = arg1.doubleValue();
366         a = 90.0 - 180.0*Math.atan(a)/Math.PI;
367         return new LispFloat(a);
368     }
369 }
370 
371 class AcothFn extends BuiltinFunction
372 {
op1(LispObject arg1)373     public LispObject op1(LispObject arg1) throws Exception
374     {
375         double a = arg1.doubleValue();
376 	if (a > -1.0 && a < 1.0) return error("bad arg for acoth");
377         a = MyMath.acoth(a);
378         return new LispFloat(a);
379     }
380 }
381 
382 class AcscFn extends BuiltinFunction
383 {
op1(LispObject arg1)384     public LispObject op1(LispObject arg1) throws Exception
385     {
386         double a = arg1.doubleValue();
387 	if (a > -1.0 && a < 1.0) return error("bad arg for acsc");
388         a = Math.asin(1.0/a);
389         return new LispFloat(a);
390     }
391 }
392 
393 class AcscdFn extends BuiltinFunction
394 {
op1(LispObject arg1)395     public LispObject op1(LispObject arg1) throws Exception
396     {
397         double a = arg1.doubleValue();
398 	if (a > -1.0 && a < 1.0) return error("bad arg for acscd");
399         a = 180.0*Math.asin(1.0/a)/Math.PI;
400         return new LispFloat(a);
401     }
402 }
403 
404 class AcschFn extends BuiltinFunction
405 {
op1(LispObject arg1)406     public LispObject op1(LispObject arg1) throws Exception
407     {
408         double a = arg1.doubleValue();
409         a = MyMath.acsch(a);
410         return new LispFloat(a);
411     }
412 }
413 
414 class Add1Fn extends BuiltinFunction
415 {
op1(LispObject arg1)416     public LispObject op1(LispObject arg1) throws Exception
417     {
418         return arg1.add1();
419     }
420 }
421 
422 class AsecFn extends BuiltinFunction
423 {
op1(LispObject arg1)424     public LispObject op1(LispObject arg1) throws Exception
425     {
426         double a = arg1.doubleValue();
427 	if (a > -1.0 && a < 1.0) return error("bad arg for asec");
428         a = Math.acos(1.0/a);
429         return new LispFloat(a);
430     }
431 }
432 
433 class AsecdFn extends BuiltinFunction
434 {
op1(LispObject arg1)435     public LispObject op1(LispObject arg1) throws Exception
436     {
437         double a = arg1.doubleValue();
438 	if (a > -1.0 && a < 1.0) return error("bad arg for asecd");
439         a = 180.0*Math.acos(1.0/a)/Math.PI;
440         return new LispFloat(a);
441     }
442 }
443 
444 class AsechFn extends BuiltinFunction
445 {
op1(LispObject arg1)446     public LispObject op1(LispObject arg1) throws Exception
447     {
448         double a = arg1.doubleValue();
449 	if (a < 0.0 || a > 1.0) return error("bad arg for asech");
450         a = MyMath.asech(a);
451         return new LispFloat(a);
452     }
453 }
454 
455 class AshFn extends BuiltinFunction
456 {
457 // Shift - thinking of things as twos-complement binary numbers
op2(LispObject arg1, LispObject arg2)458     public LispObject op2(LispObject arg1, LispObject arg2) throws Exception
459     {
460         return arg1.ash(((LispSmallInteger)arg2).value);
461     }
462 }
463 
464 class Ash1Fn extends BuiltinFunction
465 {
466 // Shift - thinking of things as sign-and-magnitude numbers
op2(LispObject arg1, LispObject arg2)467     public LispObject op2(LispObject arg1, LispObject arg2) throws Exception
468     {
469         return arg1.ash1(((LispSmallInteger)arg2).value);
470     }
471 }
472 
473 class AsinFn extends BuiltinFunction
474 {
op1(LispObject arg1)475     public LispObject op1(LispObject arg1) throws Exception
476     {
477         double a = arg1.doubleValue();
478 	if (a < -1.0 || a > 1.0) return error("bad arg for asin");
479         a = Math.asin(a);
480         return new LispFloat(a);
481     }
482 }
483 
484 class AsindFn extends BuiltinFunction
485 {
op1(LispObject arg1)486     public LispObject op1(LispObject arg1) throws Exception
487     {
488         double a = arg1.doubleValue();
489 	if (a < -1.0 || a > 1.0) return error("bad arg for asind");
490         a = 180.0*Math.asin(a)/Math.PI;
491         return new LispFloat(a);
492     }
493 }
494 
495 class AsinhFn extends BuiltinFunction
496 {
op1(LispObject arg1)497     public LispObject op1(LispObject arg1) throws Exception
498     {
499         double a = arg1.doubleValue();
500         a = MyMath.asinh(a);
501         return new LispFloat(a);
502     }
503 }
504 
505 
506 class CeilingFn extends BuiltinFunction
507 {
op1(LispObject arg1)508     public LispObject op1(LispObject arg1) throws Exception
509     {
510         return arg1.ceiling();
511     }
512 }
513 
514 class AtanFn extends BuiltinFunction
515 {
op1(LispObject arg1)516     public LispObject op1(LispObject arg1) throws Exception
517     {
518         double a = arg1.doubleValue();
519         a = Math.atan(a);
520         return new LispFloat(a);
521     }
522 }
523 
524 class Atan2Fn extends BuiltinFunction
525 {
op2(LispObject arg1, LispObject arg2)526     public LispObject op2(LispObject arg1, LispObject arg2) throws Exception
527     {
528         double a = arg1.doubleValue();
529         double b = arg2.doubleValue();
530         a = Math.atan2(a, b);
531         return new LispFloat(a);
532     }
533 }
534 
535 class Atan2dFn extends BuiltinFunction
536 {
op2(LispObject arg1, LispObject arg2)537     public LispObject op2(LispObject arg1, LispObject arg2) throws Exception
538     {
539         double a = arg1.doubleValue();
540         double b = arg2.doubleValue();
541         a = 180.0*Math.atan2(a, b)/Math.PI;
542         return new LispFloat(a);
543     }
544 }
545 
546 class AtandFn extends BuiltinFunction
547 {
op1(LispObject arg1)548     public LispObject op1(LispObject arg1) throws Exception
549     {
550         double a = arg1.doubleValue();
551         a = 180.0*Math.atan(a)/Math.PI;
552         return new LispFloat(a);
553     }
554 }
555 
556 class AtanhFn extends BuiltinFunction
557 {
op1(LispObject arg1)558     public LispObject op1(LispObject arg1) throws Exception
559     {
560         double a = arg1.doubleValue();
561 	if (a > 1.0 || a < -1.0) return error("bad arg for atanh");
562         a = MyMath.atanh(a);
563         return new LispFloat(a);
564     }
565 }
566 
567 class CosFn extends BuiltinFunction
568 {
op1(LispObject arg1)569     public LispObject op1(LispObject arg1) throws Exception
570     {
571         double a = arg1.doubleValue();
572         a = Math.cos(a);
573         return new LispFloat(a);
574     }
575 }
576 
577 class CosdFn extends BuiltinFunction
578 {
op1(LispObject arg1)579     public LispObject op1(LispObject arg1) throws Exception
580     {
581         double a = arg1.doubleValue();
582         a = Math.cos(Math.PI*a/180.0);
583         return new LispFloat(a);
584     }
585 }
586 
587 class CoshFn extends BuiltinFunction
588 {
op1(LispObject arg1)589     public LispObject op1(LispObject arg1) throws Exception
590     {
591         double a = arg1.doubleValue();
592         a = MyMath.cosh(a);
593         return new LispFloat(a);
594     }
595 }
596 
597 class CotFn extends BuiltinFunction
598 {
op1(LispObject arg1)599     public LispObject op1(LispObject arg1) throws Exception
600     {
601         double a = arg1.doubleValue();
602         a = 1.0/Math.tan(a);
603         return new LispFloat(a);
604     }
605 
606 }
607 
608 class CotdFn extends BuiltinFunction
609 {
op1(LispObject arg1)610     public LispObject op1(LispObject arg1) throws Exception
611     {
612         double a = arg1.doubleValue();
613         a = 1.0/Math.tan(Math.PI*a/180.0);
614         return new LispFloat(a);
615     }
616 }
617 
618 class CothFn extends BuiltinFunction
619 {
op1(LispObject arg1)620     public LispObject op1(LispObject arg1) throws Exception
621     {
622         double a = arg1.doubleValue();
623         a = MyMath.coth(a);
624         return new LispFloat(a);
625     }
626 }
627 
628 class CscFn extends BuiltinFunction
629 {
op1(LispObject arg1)630     public LispObject op1(LispObject arg1) throws Exception
631     {
632         double a = arg1.doubleValue();
633         a = 1.0/Math.sin(a);
634         return new LispFloat(a);
635     }
636 }
637 
638 class CscdFn extends BuiltinFunction
639 {
op1(LispObject arg1)640     public LispObject op1(LispObject arg1) throws Exception
641     {
642         double a = arg1.doubleValue();
643         a = 1.0/Math.sin(Math.PI*a/180.0);
644         return new LispFloat(a);
645     }
646 }
647 
648 class CschFn extends BuiltinFunction
649 {
op1(LispObject arg1)650     public LispObject op1(LispObject arg1) throws Exception
651     {
652         double a = arg1.doubleValue();
653         a = MyMath.csch(a);
654         return new LispFloat(a);
655     }
656 }
657 
658 class DifferenceFn extends BuiltinFunction
659 {
op2(LispObject arg1, LispObject arg2)660     public LispObject op2(LispObject arg1, LispObject arg2) throws Exception
661     {
662         return arg1.subtract(arg2);
663     }
664 }
665 
666 class DivideFn extends BuiltinFunction
667 {
op2(LispObject arg1, LispObject arg2)668     public LispObject op2(LispObject arg1, LispObject arg2) throws Exception
669     {
670         return arg1.quotientAndRemainder(arg2);
671     }
672 }
673 
674 class EvenpFn extends BuiltinFunction
675 {
op1(LispObject arg1)676     public LispObject op1(LispObject arg1) throws Exception
677     {
678         return arg1.evenp();
679     }
680 }
681 
682 class ExpFn extends BuiltinFunction
683 {
op1(LispObject arg1)684     public LispObject op1(LispObject arg1) throws Exception
685     {
686         double a = arg1.doubleValue();
687         a = Math.exp(a);
688         return new LispFloat(a);
689     }
690 }
691 
692 class ExptFn extends BuiltinFunction
693 {
op2(LispObject arg1, LispObject arg2)694     public LispObject op2(LispObject arg1, LispObject arg2) throws Exception
695     {
696         return arg1.expt(arg2);
697     }
698 }
699 
700 class FindGnuplotFn extends BuiltinFunction
701 {
op0(LispObject arg1)702     public LispObject op0(LispObject arg1) throws Exception
703     {
704         return new LispString("gnuplot");
705     }
706 }
707 
708 
709 class FixFn extends BuiltinFunction
710 {
op1(LispObject arg1)711     public LispObject op1(LispObject arg1) throws Exception
712     {
713         return arg1.fix();
714     }
715 }
716 
717 
718 class EqSafeFn extends BuiltinFunction
719 {
op1(LispObject arg1)720     public LispObject op1(LispObject arg1) throws Exception
721     {
722 // I have made Jlisp's version of EQ test small integers in an expensive
723 // way so I can report as I do here. This is for better compatibility
724 // with CSL and PSL despite a performance hit.
725         if (arg1 instanceof Symbol ||
726             arg1 instanceof LispSmallInteger) return Jlisp.lispTrue;
727         else return Jlisp.nil;
728     }
729 }
730 
731 class FixpFn extends BuiltinFunction
732 {
op1(LispObject arg1)733     public LispObject op1(LispObject arg1) throws Exception
734     {
735         return arg1.fixp();
736     }
737 }
738 
739 class FloatFn extends BuiltinFunction
740 {
op1(LispObject arg1)741     public LispObject op1(LispObject arg1) throws Exception
742     {
743         return arg1.jfloat();
744     }
745 }
746 
747 class FloatpFn extends BuiltinFunction
748 {
op1(LispObject arg1)749     public LispObject op1(LispObject arg1) throws Exception
750     {
751         return arg1.floatp();
752     }
753 }
754 
755 class FloorFn extends BuiltinFunction
756 {
op1(LispObject arg1)757     public LispObject op1(LispObject arg1) throws Exception
758     {
759         return arg1.floor();
760     }
761 }
762 
763 class FrexpFn extends BuiltinFunction
764 {
op1(LispObject arg1)765     public LispObject op1(LispObject arg1) throws Exception
766     {
767         double d = ((LispFloat)arg1).value;
768         if (d == 0.0) return new Cons(LispInteger.valueOf(0), arg1);
769 	long l = Double.doubleToLongBits(d);
770 	long x = (l >> 52) & 0x7ff;
771 // NaN and infinity do not normalise a lot
772         if (x == 0x7ff) return new Cons(LispInteger.valueOf(0), arg1);
773         if (x == 0) // a denormalised number
774         {   long s = l & 0x8000000000000000L;
775             while ((l & 0x0010000000000000L) == 0)
776             {   x--;
777                 l = l << 1;
778             }
779             l = s | (l & 0x000fffffffffffffL);
780         }
781         x = x - 0x3fe;
782 	l = (l & 0x800fffffffffffffL) | 0x3fe0000000000000L;
783 	return new Cons(LispInteger.valueOf((int)x),
784 	                new LispFloat(Double.longBitsToDouble(l)));
785     }
786 }
787 
788 class GcdnFn extends BuiltinFunction
789 {
op0()790     public LispObject op0()
791     { return LispInteger.valueOf(0); }
op1(LispInteger a1)792     public LispObject op1(LispInteger a1)
793     { return a1; }
op2(LispObject arg1, LispObject arg2)794     public LispObject op2(LispObject arg1, LispObject arg2) throws Exception
795     {
796         return arg1.gcd(arg2);
797     }
opn(LispObject [] args)798     public LispObject opn(LispObject [] args) throws Exception
799     {
800         BigInteger r = args[0].bigIntValue();
801         for (int i=2; i<args.length; i++)
802             r = r.gcd(args[i].bigIntValue());
803         return LispInteger.valueOf(r);
804     }
805 }
806 
807 class GeqFn extends BuiltinFunction
808 {
op2(LispObject arg1, LispObject arg2)809     public LispObject op2(LispObject arg1, LispObject arg2) throws Exception
810     {
811         return arg1.geq(arg2) ? Jlisp.lispTrue : Jlisp.nil;
812     }
813 }
814 
815 class EqnFn extends BuiltinFunction
816 {
op2(LispObject arg1, LispObject arg2)817     public LispObject op2(LispObject arg1, LispObject arg2) throws Exception
818     {
819         return arg1.eqn(arg2) ? Jlisp.lispTrue : Jlisp.nil;
820     }
821 }
822 
823 
824 class GreaterpFn extends BuiltinFunction
825 {
op2(LispObject arg1, LispObject arg2)826     public LispObject op2(LispObject arg1, LispObject arg2) throws Exception
827     {
828         return arg1.ge(arg2) ? Jlisp.lispTrue : Jlisp.nil;
829     }
830 }
831 
832 class HypotFn extends BuiltinFunction
833 {
op2(LispObject arg1, LispObject arg2)834     public LispObject op2(LispObject arg1, LispObject arg2) throws Exception
835     {
836         double a = arg1.doubleValue();
837         double b = arg2.doubleValue();
838         double d = Math.sqrt(a*a + b*b);
839         return new LispFloat(d);
840     }
841 }
842 
843 class Iadd1Fn extends BuiltinFunction
844 {
op1(LispObject arg1)845     public LispObject op1(LispObject arg1) throws Exception
846     {
847         return arg1.add1();
848     }
849 }
850 
851 class Id2stringFn extends BuiltinFunction
852 {
op1(LispObject arg1)853     public LispObject op1(LispObject arg1) throws Exception
854     {
855         if (!(arg1 instanceof Symbol)) return error("not an identifier for id2string");
856         ((Symbol)arg1).completeName();
857         return new LispString(((Symbol)arg1).pname);
858     }
859 }
860 
861 class IdifferenceFn extends BuiltinFunction
862 {
op2(LispObject arg1, LispObject arg2)863     public LispObject op2(LispObject arg1, LispObject arg2) throws Exception
864     {
865         return arg1.subtract(arg2);
866     }
867 }
868 
869 class IgeqFn extends BuiltinFunction
870 {
op2(LispObject arg1, LispObject arg2)871     public LispObject op2(LispObject arg1, LispObject arg2) throws Exception
872     {
873         if (arg1.geq(arg2)) return Jlisp.lispTrue;
874         else return Jlisp.nil;
875     }
876 }
877 
878 class IgreaterpFn extends BuiltinFunction
879 {
op2(LispObject arg1, LispObject arg2)880     public LispObject op2(LispObject arg1, LispObject arg2) throws Exception
881     {
882         if (arg1.ge(arg2)) return Jlisp.lispTrue;
883         else return Jlisp.nil;
884     }
885 }
886 
887 class IleqFn extends BuiltinFunction
888 {
op2(LispObject arg1, LispObject arg2)889     public LispObject op2(LispObject arg1, LispObject arg2) throws Exception
890     {
891         if (arg1.leq(arg2)) return Jlisp.lispTrue;
892         else return Jlisp.nil;
893     }
894 }
895 
896 class IlesspFn extends BuiltinFunction
897 {
op2(LispObject arg1, LispObject arg2)898     public LispObject op2(LispObject arg1, LispObject arg2) throws Exception
899     {
900         if (arg1.le(arg2)) return Jlisp.lispTrue;
901         else return Jlisp.nil;
902     }
903 }
904 
905 class IlogandFn extends BuiltinFunction
906 {
op0()907     public LispObject op0()
908     { return LispInteger.valueOf(-1); }
op1(LispInteger a1)909     public LispObject op1(LispInteger a1)
910     { return a1; }
op2(LispObject arg1, LispObject arg2)911     public LispObject op2(LispObject arg1, LispObject arg2) throws Exception
912     {
913         return arg1.and(arg2);
914     }
opn(LispObject [] args)915     public LispObject opn(LispObject [] args) throws Exception
916     {
917         BigInteger r = args[0].bigIntValue();
918         for (int i=2; i<args.length; i++)
919             r = r.and(args[i].bigIntValue());
920         return LispInteger.valueOf(r);
921     }
922 }
923 
924 class IlogorFn extends BuiltinFunction
925 {
op0()926     public LispObject op0()
927     { return LispInteger.valueOf(0); }
op1(LispInteger a1)928     public LispObject op1(LispInteger a1)
929     { return a1; }
op2(LispObject arg1, LispObject arg2)930     public LispObject op2(LispObject arg1, LispObject arg2) throws Exception
931     {
932         return arg1.or(arg2);
933     }
opn(LispObject [] args)934     public LispObject opn(LispObject [] args) throws Exception
935     {
936         BigInteger r = args[0].bigIntValue();
937         for (int i=2; i<args.length; i++)
938             r = r.or(args[i].bigIntValue());
939         return LispInteger.valueOf(r);
940     }
941 }
942 
943 class IlogxorFn extends BuiltinFunction
944 {
op0()945     public LispObject op0()
946     { return LispInteger.valueOf(0); }
op1(LispInteger a1)947     public LispObject op1(LispInteger a1)
948     { return a1; }
op2(LispObject arg1, LispObject arg2)949     public LispObject op2(LispObject arg1, LispObject arg2) throws Exception
950     {
951         return arg1.xor(arg2);
952     }
opn(LispObject [] args)953     public LispObject opn(LispObject [] args) throws Exception
954     {
955         BigInteger r = args[0].bigIntValue();
956         for (int i=2; i<args.length; i++)
957             r = r.xor(args[i].bigIntValue());
958         return LispInteger.valueOf(r);
959     }
960 }
961 
962 class ImaxFn extends BuiltinFunction
963 {
op1(LispObject arg1)964     public LispObject op1(LispObject arg1) { return arg1; }
op2(LispObject arg1, LispObject arg2)965     public LispObject op2(LispObject arg1, LispObject arg2) throws Exception
966     {
967         return arg1.max(arg2);
968     }
opn(LispObject [] args)969     public LispObject opn(LispObject [] args) throws Exception
970     {
971         LispObject r = args[0];
972         for (int i=1; i<args.length; i++)
973             r = r.max(args[i]);
974         return r;
975     }
976 }
977 
978 class IminFn extends BuiltinFunction
979 {
op1(LispObject arg1)980     public LispObject op1(LispObject arg1) { return arg1; }
op2(LispObject arg1, LispObject arg2)981     public LispObject op2(LispObject arg1, LispObject arg2) throws Exception
982     {
983         return arg1.min(arg2);
984     }
opn(LispObject [] args)985     public LispObject opn(LispObject [] args) throws Exception
986     {
987         LispObject r = args[0];
988         for (int i=1; i<args.length; i++)
989             r = r.min(args[i]);
990         return r;
991     }
992 }
993 
994 class IminusFn extends BuiltinFunction
995 {
op1(LispObject arg1)996     public LispObject op1(LispObject arg1) throws Exception
997     {
998         return arg1.negate();
999     }
1000 }
1001 
1002 class IminuspFn extends BuiltinFunction
1003 {
op1(LispObject arg1)1004     public LispObject op1(LispObject arg1) throws Exception
1005     {
1006         return arg1.minusp();
1007     }
1008 }
1009 
1010 class IntegerpFn extends BuiltinFunction
1011 {
op1(LispObject arg1)1012     public LispObject op1(LispObject arg1) throws Exception
1013     {
1014         return arg1.integerp();
1015     }
1016 }
1017 
1018 class IonepFn extends BuiltinFunction
1019 {
op1(LispObject arg1)1020     public LispObject op1(LispObject arg1) throws Exception
1021     {
1022         return arg1.onep();
1023     }
1024 }
1025 
1026 class IplusFn extends BuiltinFunction
1027 {
op0()1028     public LispObject op0() { return LispInteger.valueOf(0); }
op1(LispObject arg1)1029     public LispObject op1(LispObject arg1) { return arg1; }
op2(LispObject arg1, LispObject arg2)1030     public LispObject op2(LispObject arg1, LispObject arg2) throws Exception
1031     {
1032         return arg1.add(arg2);
1033     }
opn(LispObject [] args)1034     public LispObject opn(LispObject [] args) throws Exception
1035     {
1036         LispObject r = args[0];
1037         for (int i=1; i<args.length; i++)
1038             r = r.add(args[i]);
1039         return r;
1040     }
1041 }
1042 
1043 class Iplus2Fn extends BuiltinFunction
1044 {
op2(LispObject arg1, LispObject arg2)1045     public LispObject op2(LispObject arg1, LispObject arg2) throws Exception
1046     {
1047         return arg1.add(arg2);
1048     }
1049 }
1050 
1051 class IquotientFn extends BuiltinFunction
1052 {
op2(LispObject arg1, LispObject arg2)1053     public LispObject op2(LispObject arg1, LispObject arg2) throws Exception
1054     {
1055         return arg1.divide(arg2);
1056     }
1057 }
1058 
1059 class IremainderFn extends BuiltinFunction
1060 {
op2(LispObject arg1, LispObject arg2)1061     public LispObject op2(LispObject arg1, LispObject arg2) throws Exception
1062     {
1063         return arg1.remainder(arg2);
1064     }
1065 }
1066 
1067 class AshiftFn extends BuiltinFunction
1068 {
op2(LispObject arg1, LispObject arg2)1069     public LispObject op2(LispObject arg1, LispObject arg2) throws Exception
1070     {
1071         int n = ((LispSmallInteger)arg2).value;
1072         if (n < 0) return arg1.rightshift(-n);
1073         else return arg1.leftshift(n);
1074     }
1075 }
1076 
1077 class LshiftFn extends BuiltinFunction
1078 {
op2(LispObject arg1, LispObject arg2)1079     public LispObject op2(LispObject arg1, LispObject arg2) throws Exception
1080     {
1081         int n = ((LispSmallInteger)arg2).value;
1082         if (n < 0) return arg1.rightshift(-n);
1083         else return arg1.leftshift(n);
1084     }
1085 }
1086 
1087 class IrightshiftFn extends BuiltinFunction
1088 {
op2(LispObject arg1, LispObject arg2)1089     public LispObject op2(LispObject arg1, LispObject arg2) throws Exception
1090     {
1091         return arg1.rightshift(((LispSmallInteger)arg2).value);
1092     }
1093 }
1094 
1095 class Isub1Fn extends BuiltinFunction
1096 {
op1(LispObject arg1)1097     public LispObject op1(LispObject arg1) throws Exception
1098     {
1099         return arg1.sub1();
1100     }
1101 }
1102 
1103 class ItimesFn extends BuiltinFunction
1104 {
op0()1105     public LispObject op0() { return LispInteger.valueOf(1); }
op1(LispObject arg1)1106     public LispObject op1(LispObject arg1) { return arg1; }
op2(LispObject arg1, LispObject arg2)1107     public LispObject op2(LispObject arg1, LispObject arg2) throws Exception
1108     {
1109         return arg1.multiply(arg2);
1110     }
opn(LispObject [] args)1111     public LispObject opn(LispObject [] args) throws Exception
1112     {
1113         LispObject r = args[0];
1114         for (int i=1; i<args.length; i++)
1115             r = r.multiply(args[i]);
1116         return r;
1117     }
1118 }
1119 
1120 class Itimes2Fn extends BuiltinFunction
1121 {
op2(LispObject arg1, LispObject arg2)1122     public LispObject op2(LispObject arg1, LispObject arg2) throws Exception
1123     {
1124         return arg1.multiply(arg2);
1125     }
1126 }
1127 
1128 class IzeropFn extends BuiltinFunction
1129 {
op1(LispObject arg1)1130     public LispObject op1(LispObject arg1) throws Exception
1131     {
1132         return arg1.zerop();
1133     }
1134 }
1135 
1136 class LcmnFn extends BuiltinFunction
1137 {
op0()1138     public LispObject op0()
1139     { return LispInteger.valueOf(1); }
op1(LispInteger a1)1140     public LispObject op1(LispInteger a1)
1141     { return a1; }
op2(LispObject arg1, LispObject arg2)1142     public LispObject op2(LispObject arg1, LispObject arg2) throws Exception
1143     {
1144         return arg1.lcm(arg2);
1145     }
opn(LispObject [] args)1146     public LispObject opn(LispObject [] args) throws Exception
1147     {
1148         BigInteger r = args[0].bigIntValue();
1149         for (int i=2; i<args.length; i++)
1150             r = LispBigInteger.biglcm(r, args[i].bigIntValue());
1151         return LispInteger.valueOf(r);
1152     }
1153 }
1154 
1155 class LeqFn extends BuiltinFunction
1156 {
op2(LispObject arg1, LispObject arg2)1157     public LispObject op2(LispObject arg1, LispObject arg2) throws Exception
1158     {
1159         return arg1.leq(arg2) ? Jlisp.lispTrue : Jlisp.nil;
1160     }
1161 }
1162 
1163 class LesspFn extends BuiltinFunction
1164 {
op2(LispObject arg1, LispObject arg2)1165     public LispObject op2(LispObject arg1, LispObject arg2) throws Exception
1166     {
1167         return arg1.le(arg2) ? Jlisp.lispTrue : Jlisp.nil;
1168     }
1169 }
1170 
1171 class LnFn extends BuiltinFunction
1172 {
op1(LispObject arg1)1173     public LispObject op1(LispObject arg1) throws Exception
1174     {
1175         double a = arg1.doubleValue();
1176 	if (a <= 0.0) return error("bad arg for ln");
1177         a = Math.log(a);
1178         return new LispFloat(a);
1179     }
1180 }
1181 
1182 class LogFn extends BuiltinFunction
1183 {
op1(LispObject arg1)1184     public LispObject op1(LispObject arg1) throws Exception
1185     {
1186         double a = arg1.doubleValue();
1187 	if (a <= 0.0) return error("bad arg for log");
1188         a = Math.log(a);
1189         return new LispFloat(a);
1190     }
op2(LispObject arg1, LispObject arg2)1191     public LispObject op2(LispObject arg1, LispObject arg2) throws Exception
1192     {
1193         double a1 = arg1.doubleValue();
1194         double a2 = arg2.doubleValue();
1195 	if (a1 <= 0.0 || a2 <= 0.0) return error("bad arg for log");
1196         a1 = Math.log(a1)/Math.log(a2);
1197         return new LispFloat(a1);
1198     }
1199 }
1200 
1201 class Log10Fn extends BuiltinFunction
1202 {
1203     final double log10 = Math.log(10.0);
op1(LispObject arg1)1204     public LispObject op1(LispObject arg1) throws Exception
1205     {
1206         double a = arg1.doubleValue();
1207 	if (a <= 0.0) return error("bad arg for log10");
1208         a = Math.log(a)/log10;
1209         return new LispFloat(a);
1210     }
1211 }
1212 
1213 class LogandFn extends BuiltinFunction
1214 {
op0()1215     public LispObject op0()
1216     { return LispInteger.valueOf(-1); }
op1(LispInteger a1)1217     public LispObject op1(LispInteger a1)
1218     { return a1; }
op2(LispObject arg1, LispObject arg2)1219     public LispObject op2(LispObject arg1, LispObject arg2) throws Exception
1220     {
1221         return arg1.and(arg2);
1222     }
opn(LispObject [] args)1223     public LispObject opn(LispObject [] args) throws Exception
1224     {
1225         BigInteger r = args[0].bigIntValue();
1226         for (int i=2; i<args.length; i++)
1227             r = r.and(args[i].bigIntValue());
1228         return LispInteger.valueOf(r);
1229     }
1230 }
1231 
1232 class LogbFn extends BuiltinFunction
1233 {
op2(LispObject arg1, LispObject arg2)1234     public LispObject op2(LispObject arg1, LispObject arg2) throws Exception
1235     {
1236         double a1 = arg1.doubleValue();
1237         double a2 = arg2.doubleValue();
1238 	if (a1 <= 0.0 || a2 <= 0.0) return error("bad arg for logb");
1239         a1 = Math.log(a1)/Math.log(a2);
1240         return new LispFloat(a1);
1241     }
1242 }
1243 
1244 class LogeqvFn extends BuiltinFunction
1245 {
op0()1246     public LispObject op0()
1247     { return LispInteger.valueOf(-1); }
op1(LispInteger a1)1248     public LispObject op1(LispInteger a1)
1249     { return a1; }
op2(LispObject arg1, LispObject arg2)1250     public LispObject op2(LispObject arg1, LispObject arg2) throws Exception
1251     {
1252         return arg1.xor(arg2);
1253     }
opn(LispObject [] args)1254     public LispObject opn(LispObject [] args) throws Exception
1255     {
1256         BigInteger r = args[0].bigIntValue();
1257         for (int i=2; i<args.length; i++)
1258             r = r.xor(args[i].bigIntValue()).not();
1259         return LispInteger.valueOf(r);
1260     }
1261 
1262 }
1263 
1264 class LognotFn extends BuiltinFunction
1265 {
op1(LispObject arg1)1266     public LispObject op1(LispObject arg1) throws Exception
1267     {
1268         return arg1.not();
1269     }
1270 }
1271 
1272 class LogorFn extends BuiltinFunction
1273 {
op0()1274     public LispObject op0()
1275     { return LispInteger.valueOf(0); }
op1(LispInteger a1)1276     public LispObject op1(LispInteger a1)
1277     { return a1; }
op2(LispObject arg1, LispObject arg2)1278     public LispObject op2(LispObject arg1, LispObject arg2) throws Exception
1279     {
1280         return arg1.or(arg2);
1281     }
opn(LispObject [] args)1282     public LispObject opn(LispObject [] args) throws Exception
1283     {
1284         BigInteger r = args[0].bigIntValue();
1285         for (int i=2; i<args.length; i++)
1286             r = r.or(args[i].bigIntValue());
1287         return LispInteger.valueOf(r);
1288     }
1289 }
1290 
1291 class LogxorFn extends BuiltinFunction
1292 {
op0()1293     public LispObject op0()
1294     { return LispInteger.valueOf(0); }
op1(LispInteger a1)1295     public LispObject op1(LispInteger a1)
1296     { return a1; }
op2(LispObject arg1, LispObject arg2)1297     public LispObject op2(LispObject arg1, LispObject arg2) throws Exception
1298     {
1299         return arg1.xor(arg2);
1300     }
opn(LispObject [] args)1301     public LispObject opn(LispObject [] args) throws Exception
1302     {
1303         BigInteger r = args[0].bigIntValue();
1304         for (int i=2; i<args.length; i++)
1305             r = r.xor(args[i].bigIntValue());
1306         return LispInteger.valueOf(r);
1307     }
1308 }
1309 
1310 class Lose_precisionFn extends BuiltinFunction
1311 {
op1(LispObject arg1)1312     public LispObject op1(LispObject arg1) throws Exception
1313     {
1314         return error(name + " not yet implemented");
1315     }
1316 }
1317 
1318 class LsdFn extends BuiltinFunction
1319 {
op1(LispObject arg1)1320     public LispObject op1(LispObject arg1) throws Exception
1321     {
1322         return arg1.lsd();
1323     }
1324 }
1325 
1326 class MinusFn extends BuiltinFunction
1327 {
op1(LispObject arg1)1328     public LispObject op1(LispObject arg1) throws Exception
1329     {
1330         return arg1.negate();
1331     }
1332 }
1333 
1334 class MinuspFn extends BuiltinFunction
1335 {
op1(LispObject arg1)1336     public LispObject op1(LispObject arg1) throws Exception
1337     {
1338         return arg1.minusp();
1339     }
1340 }
1341 
1342 class ModFn extends BuiltinFunction
1343 {
op2(LispObject arg1, LispObject arg2)1344     public LispObject op2(LispObject arg1, LispObject arg2) throws Exception
1345     {
1346         return arg1.mod(arg2);
1347     }
1348 }
1349 
1350 class Modular_differenceFn extends BuiltinFunction
1351 {
op2(LispObject arg1, LispObject arg2)1352     public LispObject op2(LispObject arg1, LispObject arg2) throws Exception
1353     {
1354         return arg1.modSubtract(arg2);
1355     }
1356 }
1357 
1358 class Modular_exptFn extends BuiltinFunction
1359 {
op2(LispObject arg1, LispObject arg2)1360     public LispObject op2(LispObject arg1, LispObject arg2) throws Exception
1361     {
1362         return arg1.modExpt(arg2.intValue());
1363     }
1364 }
1365 
1366 class Modular_minusFn extends BuiltinFunction
1367 {
op1(LispObject arg1)1368     public LispObject op1(LispObject arg1) throws Exception
1369     {
1370         return arg1.modMinus();
1371     }
1372 }
1373 
1374 class Modular_numberFn extends BuiltinFunction
1375 {
op1(LispObject arg1)1376     public LispObject op1(LispObject arg1) throws Exception
1377     {
1378         return arg1.reduceMod();
1379     }
1380 }
1381 
1382 class Modular_plusFn extends BuiltinFunction
1383 {
op2(LispObject arg1, LispObject arg2)1384     public LispObject op2(LispObject arg1, LispObject arg2) throws Exception
1385     {
1386         return arg1.modAdd(arg2);
1387     }
1388 }
1389 
1390 class Modular_quotientFn extends BuiltinFunction
1391 {
op2(LispObject arg1, LispObject arg2)1392     public LispObject op2(LispObject arg1, LispObject arg2) throws Exception
1393     {
1394         return arg1.modDivide(arg2);
1395     }
1396 }
1397 
1398 class Modular_reciprocalFn extends BuiltinFunction
1399 {
op1(LispObject arg1)1400     public LispObject op1(LispObject arg1) throws Exception
1401     {
1402         return arg1.modRecip();
1403     }
1404 }
1405 
1406 class Safe_modular_reciprocalFn extends BuiltinFunction
1407 {
op1(LispObject arg1)1408     public LispObject op1(LispObject arg1) throws Exception
1409     {
1410         return arg1.safeModRecip();
1411     }
1412 }
1413 
1414 class Modular_timesFn extends BuiltinFunction
1415 {
op2(LispObject arg1, LispObject arg2)1416     public LispObject op2(LispObject arg1, LispObject arg2) throws Exception
1417     {
1418         return arg1.modMultiply(arg2);
1419     }
1420 }
1421 
1422 class QuotientFn extends BuiltinFunction
1423 {
op2(LispObject arg1, LispObject arg2)1424     public LispObject op2(LispObject arg1, LispObject arg2) throws Exception
1425     {
1426         return arg1.divide(arg2);
1427     }
1428 }
1429 
1430 class MsdFn extends BuiltinFunction
1431 {
op1(LispObject arg1)1432     public LispObject op1(LispObject arg1) throws Exception
1433     {
1434         return arg1.msd();
1435     }
1436 }
1437 
1438 class MvListFn extends BuiltinFunction
1439 {
1440 // In Common Lisp "mv-list" might be used to save multiple values, eg
1441 // across unwind-protect. In Standard Lisp there are no multiple values so
1442 // this has degenerate behaviour.
op1(LispObject arg1)1443     public LispObject op1(LispObject arg1) throws Exception
1444     {
1445         return new Cons(arg1, Jlisp.nil);
1446     }
1447 }
1448 
1449 class NumberpFn extends BuiltinFunction
1450 {
op1(LispObject arg1)1451     public LispObject op1(LispObject arg1)
1452     {
1453         if (arg1 instanceof LispNumber) return Jlisp.lispTrue;
1454         else return Jlisp.nil;
1455     }
1456 }
1457 
1458 class OddpFn extends BuiltinFunction
1459 {
op1(LispObject arg1)1460     public LispObject op1(LispObject arg1) throws Exception
1461     {
1462         return arg1.oddp();
1463     }
1464 }
1465 
1466 class OnepFn extends BuiltinFunction
1467 {
op1(LispObject arg1)1468     public LispObject op1(LispObject arg1) throws Exception
1469     {
1470         return arg1.onep();
1471     }
1472 }
1473 
1474 class PluspFn extends BuiltinFunction
1475 {
op1(LispObject arg1)1476     public LispObject op1(LispObject arg1) throws Exception
1477     {
1478         return arg1.plusp();
1479     }
1480 }
1481 
1482 class Random_fixnumFn extends BuiltinFunction
1483 {
op1(LispObject arg1)1484     public LispObject op1(LispObject arg1) throws Exception
1485     {
1486 // Valus a positive number that would be a fixnum in CSL!
1487         int w = Jlisp.random.nextInt() & 0x07ffffff;
1488         return LispInteger.valueOf(w);
1489     }
1490 }
1491 
1492 class Random_numberFn extends BuiltinFunction
1493 {
op1(LispObject arg1)1494     public LispObject op1(LispObject arg1) throws Exception
1495     {
1496 // Argument should be a positive integer or float...
1497         if (arg1 instanceof LispFloat)
1498             return new LispFloat(Jlisp.random.nextDouble()*
1499                                  ((LispFloat)arg1).value);
1500         BigInteger b = arg1.bigIntValue();
1501 //@@@@ Unfinished work @@@@
1502         return error(name + " not yet implemented");
1503     }
1504 }
1505 
1506 class RationalFn extends BuiltinFunction
1507 {
op1(LispObject arg1)1508     public LispObject op1(LispObject arg1) throws Exception
1509     {
1510         return error(name + " not yet implemented");
1511     }
1512 }
1513 
1514 class RemainderFn extends BuiltinFunction
1515 {
op2(LispObject arg1, LispObject arg2)1516     public LispObject op2(LispObject arg1, LispObject arg2) throws Exception
1517     {
1518         return arg1.remainder(arg2);
1519     }
1520 }
1521 
1522 class RoundFn extends BuiltinFunction
1523 {
op1(LispObject arg1)1524     public LispObject op1(LispObject arg1) throws Exception
1525     {
1526         return arg1.round();
1527     }
1528 }
1529 
1530 class SecFn extends BuiltinFunction
1531 {
op1(LispObject arg1)1532     public LispObject op1(LispObject arg1) throws Exception
1533     {
1534         double a = arg1.doubleValue();
1535         a = 1.0/Math.cos(a);
1536         return new LispFloat(a);
1537     }
1538 }
1539 
1540 class SecdFn extends BuiltinFunction
1541 {
op1(LispObject arg1)1542     public LispObject op1(LispObject arg1) throws Exception
1543     {
1544         double a = arg1.doubleValue();
1545         a = 1.0/Math.cos(Math.PI*a/180.0);
1546         return new LispFloat(a);
1547     }
1548 }
1549 
1550 class SechFn extends BuiltinFunction
1551 {
op1(LispObject arg1)1552     public LispObject op1(LispObject arg1) throws Exception
1553     {
1554         double a = arg1.doubleValue();
1555         a = MyMath.sech(a);
1556         return new LispFloat(a);
1557     }
1558 }
1559 
1560 class Set_small_modulusFn extends BuiltinFunction
1561 {
1562 // For full CSL compatibility I need to allow the modulus to be either
1563 // large or small here.
op1(LispObject arg1)1564     public LispObject op1(LispObject arg1) throws Exception
1565     {
1566         BigInteger old = Jlisp.bigModulus;
1567         if (arg1 instanceof LispSmallInteger)
1568         {   int n = ((LispSmallInteger)arg1).value;
1569             if (n <= 0)
1570                  return error("set-small-modulus needs a positive argument");
1571             Jlisp.modulus = n;
1572             Jlisp.bigModulus = BigInteger.valueOf(n);
1573             Jlisp.modulusIsBig = false;
1574         }
1575         else if (arg1 instanceof LispBigInteger)
1576         {   BigInteger n = ((LispBigInteger)arg1).value;
1577             if (n.signum() < 0)
1578                  return error("set-small-modulus needs a positive argument");
1579             Jlisp.modulus = 0;   // Invalid here!
1580             Jlisp.bigModulus = n;
1581             Jlisp.modulusIsBig = true;
1582         }
1583         else return error("arg of set-small-modulus is not an integer");
1584         return LispInteger.valueOf(old);
1585     }
1586 }
1587 
1588 class SinFn extends BuiltinFunction
1589 {
op1(LispObject arg1)1590     public LispObject op1(LispObject arg1) throws Exception
1591     {
1592         double a = arg1.doubleValue();
1593         a = Math.sin(a);
1594         return new LispFloat(a);
1595     }
1596 }
1597 
1598 class SindFn extends BuiltinFunction
1599 {
op1(LispObject arg1)1600     public LispObject op1(LispObject arg1) throws Exception
1601     {
1602         double a = arg1.doubleValue();
1603         a = Math.sin(Math.PI*a/180.0);
1604         return new LispFloat(a);
1605     }
1606 }
1607 
1608 class SinhFn extends BuiltinFunction
1609 {
op1(LispObject arg1)1610     public LispObject op1(LispObject arg1) throws Exception
1611     {
1612         double a = arg1.doubleValue();
1613         a = MyMath.sinh(a);
1614         return new LispFloat(a);
1615     }
1616 }
1617 
1618 class SqrtFn extends BuiltinFunction
1619 {
op1(LispObject arg1)1620     public LispObject op1(LispObject arg1) throws Exception
1621     {
1622         double a = arg1.doubleValue();
1623 	if (a < 0.0) return error("bad arg for sqrt");
1624         a = Math.sqrt(a);
1625         return new LispFloat(a);
1626     }
1627 }
1628 
1629 class Sub1Fn extends BuiltinFunction
1630 {
op1(LispObject arg1)1631     public LispObject op1(LispObject arg1) throws Exception
1632     {
1633         return arg1.sub1();
1634     }
1635 }
1636 
1637 class TanFn extends BuiltinFunction
1638 {
op1(LispObject arg1)1639     public LispObject op1(LispObject arg1) throws Exception
1640     {
1641         double a = arg1.doubleValue();
1642         a = Math.tan(a);
1643         return new LispFloat(a);
1644     }
1645 }
1646 
1647 class TandFn extends BuiltinFunction
1648 {
op1(LispObject arg1)1649     public LispObject op1(LispObject arg1) throws Exception
1650     {
1651         double a = arg1.doubleValue();
1652         a = Math.tan(Math.PI*a/180.0);
1653         return new LispFloat(a);
1654     }
1655 }
1656 
1657 class TanhFn extends BuiltinFunction
1658 {
op1(LispObject arg1)1659     public LispObject op1(LispObject arg1) throws Exception
1660     {
1661         double a = arg1.doubleValue();
1662         a = MyMath.tanh(a);
1663         return new LispFloat(a);
1664     }
1665 }
1666 
1667 class TruncateFn extends BuiltinFunction
1668 {
op1(LispObject arg1)1669     public LispObject op1(LispObject arg1) throws Exception
1670     {
1671         return arg1.truncate();
1672     }
1673 
op2(LispObject arg1, LispObject arg2)1674     public LispObject op2(LispObject arg1, LispObject arg2) throws Exception
1675     {
1676         double a1, a2;
1677         if (arg1 instanceof LispInteger)
1678 	{   if (arg2 instanceof LispInteger)
1679                 return arg1.divide(arg2);
1680 	    else a1 = arg1.doubleValue(); // overflow?
1681         }
1682         else a1 = ((LispFloat)arg1).value;
1683         a2 = arg2.doubleValue();
1684 // There is worry here with overflow etc. But maybe nobody ever calls this!
1685         return LispInteger.valueOf((long)(a1 / a2));
1686     }
1687 }
1688 
1689 class ZeropFn extends BuiltinFunction
1690 {
op1(LispObject arg1)1691     public LispObject op1(LispObject arg1) throws Exception
1692     {
1693         return arg1.zerop();
1694     }
1695 }
1696 
1697 // The next two are used in compiled code when handling &OPT optional
1698 // arguments.
1699 
1700 class Is_spidFn extends BuiltinFunction
1701 {
op1(LispObject arg1)1702     public LispObject op1(LispObject arg1) throws Exception
1703     {
1704         return arg1 instanceof Spid ? Jlisp.lispTrue : Jlisp.nil;
1705     }
1706 }
1707 
1708 class Spid_to_nilFn extends BuiltinFunction
1709 {
op1(LispObject arg1)1710     public LispObject op1(LispObject arg1) throws Exception
1711     {
1712         return arg1 instanceof Spid ? Jlisp.lispTrue : arg1;
1713     }
1714 }
1715 
1716 }
1717 
1718 // End of Fns2.java
1719 
1720