Build Fix -- compatibility issue with newer autoconf
[sxemacs] / src / ent / ent-indef.c
1 /*
2   ent-indef.c -- Indefinite symbols for SXEmacs
3   Copyright (C) 2005, 2006 Sebastian Freundt
4
5   Author:  Sebastian Freundt
6
7 This file is part of SXEmacs
8
9 SXEmacs is free software: you can redistribute it and/or modify
10 it under the terms of the GNU General Public License as published by
11 the Free Software Foundation, either version 3 of the License, or
12 (at your option) any later version.
13
14 SXEmacs is distributed in the hope that it will be useful,
15 but WITHOUT ANY WARRANTY; without even the implied warranty of
16 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
17 GNU General Public License for more details.
18
19 You should have received a copy of the GNU General Public License
20 along with this program.  If not, see <http://www.gnu.org/licenses/>. */
21
22
23 #include <config.h>
24 #include <limits.h>
25 #include <math.h>
26 #include "lisp.h"
27 #include "sysproc.h"    /* For qxe_getpid */
28
29 #include "ent.h"
30
31 static inline int indef_eq(Lisp_Object, Lisp_Object);
32 static inline int indef_neq(Lisp_Object, Lisp_Object);
33 static int indef_lt(Lisp_Object, Lisp_Object);
34 static int indef_gt(Lisp_Object, Lisp_Object);
35 #if 0
36 static int indef_le(Lisp_Object, Lisp_Object);
37 static int indef_ge(Lisp_Object, Lisp_Object);
38 #endif
39 static Lisp_Object indef_negate(Lisp_Object);
40
41 \f
42 Lisp_Object Vnot_a_number;
43 Lisp_Object Vpinfinity;
44 Lisp_Object Vninfinity;
45 Lisp_Object Vcomplex_infinity;
46
47 \f
48 static void
49 indef_print (Lisp_Object obj, Lisp_Object printcharfun, int SXE_UNUSED(escapeflag))
50 {
51         Bufbyte *istr = indef_to_string(XINDEF_DATA(obj));
52         write_c_string((char*)istr, printcharfun);
53         xfree(istr);
54         istr = (Bufbyte *)NULL;
55         return;
56 }
57
58 static int
59 indef_equal (Lisp_Object obj1, Lisp_Object obj2, int SXE_UNUSED(depth))
60 {
61         return (XINDEF_DATA(obj1) == XINDEF_DATA(obj2));
62 }
63
64 static unsigned long
65 indef_hash (Lisp_Object obj, int SXE_UNUSED(depth))
66 {
67         return (unsigned long)XINDEF_DATA(obj);
68 }
69
70 static const struct lrecord_description indef_description[] = {
71         { XD_INT, offsetof(Lisp_Indef, data) },
72         { XD_END }
73 };
74
75 DEFINE_BASIC_LRECORD_IMPLEMENTATION("indef", indef,
76                                     NULL, indef_print, NULL,
77                                     indef_equal, indef_hash,
78                                     indef_description, Lisp_Indef);
79
80 \f
81 Bufbyte *indef_to_string(indef i)
82 {
83         Bufbyte *str;
84
85         switch (i) {
86         case POS_INFINITY:
87                 str = xnew_atomic_array(Bufbyte, 10);
88                 memcpy((char*)str, "+infinity\000", 10);
89                 break;
90         case NEG_INFINITY:
91                 str = xnew_atomic_array(Bufbyte, 10);
92                 memcpy((char*)str, "-infinity\000", 10);
93                 break;
94         case NOT_A_NUMBER:
95                 str = xnew_atomic_array(Bufbyte, 13);
96                 memcpy((char*)str, "not-a-number\000", 13);
97                 break;
98         case COMPLEX_INFINITY:
99                 str = xnew_atomic_array(Bufbyte, 17);
100                 memcpy((char*)str, "complex-infinity\000", 17);
101                 break;
102         case END_OF_COMPARABLE_INFINITIES:
103         case END_OF_INFINITIES:
104         case NUMBER_INDEFS:
105         default:
106                 str = xnew_atomic_array(Bufbyte, 26);
107                 memcpy((char*)str, "unknown indefinite symbol\000", 26);
108                 break;
109         }
110
111         return str;
112 }
113
114 static Lisp_Object
115 ent_lift_indef(Lisp_Object number, ent_lift_args_t SXE_UNUSED(unused))
116 {
117         if (INFINITYP(number))
118                 return number;
119         else
120                 signal_error(Qdomain_error, list1(number));
121
122         return Qnil;
123 }
124
125 Lisp_Object
126 ent_lift_INDEF_T_COMPARABLE(Lisp_Object number, ent_lift_args_t SXE_UNUSED(unused))
127 {
128         if (COMPARABLE_INDEF_P(number))
129                 return number;
130         else
131                 signal_error(Qdomain_error, list1(number));
132
133         return Qnil;
134 }
135
136 static indef ent_optable_indef_sum[NUMBER_INDEFS][NUMBER_INDEFS];
137 static indef ent_optable_indef_diff[NUMBER_INDEFS][NUMBER_INDEFS];
138 static indef ent_optable_indef_prod[NUMBER_INDEFS][NUMBER_INDEFS];
139 static indef ent_optable_indef_div[NUMBER_INDEFS][NUMBER_INDEFS];
140 static indef ent_optable_indef_rem[NUMBER_INDEFS][NUMBER_INDEFS];
141 static indef ent_optable_indef_pow[NUMBER_INDEFS][NUMBER_INDEFS];
142
143 static void init_indef_table(void)
144 {
145         indef i;
146
147         /* initialise NOT_A_NUMBER stuff */
148         for (i = 0; i < NUMBER_INDEFS; i++) {
149                 ent_optable_indef_sum[NOT_A_NUMBER][i] = NOT_A_NUMBER;
150                 ent_optable_indef_sum[i][NOT_A_NUMBER] = NOT_A_NUMBER;
151                 ent_optable_indef_diff[NOT_A_NUMBER][i] = NOT_A_NUMBER;
152                 ent_optable_indef_diff[i][NOT_A_NUMBER] = NOT_A_NUMBER;
153                 ent_optable_indef_prod[NOT_A_NUMBER][i] = NOT_A_NUMBER;
154                 ent_optable_indef_prod[i][NOT_A_NUMBER] = NOT_A_NUMBER;
155                 ent_optable_indef_div[NOT_A_NUMBER][i] = NOT_A_NUMBER;
156                 ent_optable_indef_div[i][NOT_A_NUMBER] = NOT_A_NUMBER;
157                 ent_optable_indef_rem[NOT_A_NUMBER][i] = NOT_A_NUMBER;
158                 ent_optable_indef_rem[i][NOT_A_NUMBER] = NOT_A_NUMBER;
159                 ent_optable_indef_pow[NOT_A_NUMBER][i] = NOT_A_NUMBER;
160                 ent_optable_indef_pow[i][NOT_A_NUMBER] = NOT_A_NUMBER;
161         }
162
163         /* Addition table */
164         ent_optable_indef_sum[POS_INFINITY][POS_INFINITY] = POS_INFINITY;
165         ent_optable_indef_sum[POS_INFINITY][NEG_INFINITY] = NOT_A_NUMBER;
166         ent_optable_indef_sum[POS_INFINITY][COMPLEX_INFINITY] = NOT_A_NUMBER;
167
168         ent_optable_indef_sum[NEG_INFINITY][POS_INFINITY] = NOT_A_NUMBER;
169         ent_optable_indef_sum[NEG_INFINITY][NEG_INFINITY] = NEG_INFINITY;
170         ent_optable_indef_sum[NEG_INFINITY][COMPLEX_INFINITY] = NOT_A_NUMBER;
171
172         ent_optable_indef_sum[COMPLEX_INFINITY][POS_INFINITY] = NOT_A_NUMBER;
173         ent_optable_indef_sum[COMPLEX_INFINITY][NEG_INFINITY] = NOT_A_NUMBER;
174         ent_optable_indef_sum[COMPLEX_INFINITY][COMPLEX_INFINITY] =
175                 COMPLEX_INFINITY;
176
177         /* Subtraction table */
178         ent_optable_indef_diff[POS_INFINITY][POS_INFINITY] = NOT_A_NUMBER;
179         ent_optable_indef_diff[POS_INFINITY][NEG_INFINITY] = POS_INFINITY;
180         ent_optable_indef_diff[POS_INFINITY][COMPLEX_INFINITY] = NOT_A_NUMBER;
181
182         ent_optable_indef_diff[NEG_INFINITY][POS_INFINITY] = NEG_INFINITY;
183         ent_optable_indef_diff[NEG_INFINITY][NEG_INFINITY] = NOT_A_NUMBER;
184         ent_optable_indef_diff[NEG_INFINITY][COMPLEX_INFINITY] = NOT_A_NUMBER;
185
186         ent_optable_indef_diff[COMPLEX_INFINITY][POS_INFINITY] = NOT_A_NUMBER;
187         ent_optable_indef_diff[COMPLEX_INFINITY][NEG_INFINITY] = NOT_A_NUMBER;
188         ent_optable_indef_diff[COMPLEX_INFINITY][COMPLEX_INFINITY] =
189                 COMPLEX_INFINITY;
190
191         /* Multiplication table */
192         ent_optable_indef_prod[POS_INFINITY][POS_INFINITY] = POS_INFINITY;
193         ent_optable_indef_prod[POS_INFINITY][NEG_INFINITY] = NEG_INFINITY;
194         ent_optable_indef_prod[POS_INFINITY][COMPLEX_INFINITY] =
195                 COMPLEX_INFINITY;
196
197         ent_optable_indef_prod[NEG_INFINITY][POS_INFINITY] = NEG_INFINITY;
198         ent_optable_indef_prod[NEG_INFINITY][NEG_INFINITY] = POS_INFINITY;
199         ent_optable_indef_prod[NEG_INFINITY][COMPLEX_INFINITY] =
200                 COMPLEX_INFINITY;
201
202         ent_optable_indef_prod[COMPLEX_INFINITY][POS_INFINITY] =
203                 COMPLEX_INFINITY;
204         ent_optable_indef_prod[COMPLEX_INFINITY][NEG_INFINITY] =
205                 COMPLEX_INFINITY;
206         ent_optable_indef_prod[COMPLEX_INFINITY][COMPLEX_INFINITY] =
207                 COMPLEX_INFINITY;
208
209         /* Division table */
210         ent_optable_indef_div[POS_INFINITY][POS_INFINITY] = NOT_A_NUMBER;
211         ent_optable_indef_div[POS_INFINITY][NEG_INFINITY] = NOT_A_NUMBER;
212         ent_optable_indef_div[POS_INFINITY][COMPLEX_INFINITY] =
213                 COMPLEX_INFINITY;
214
215         ent_optable_indef_div[NEG_INFINITY][POS_INFINITY] = NOT_A_NUMBER;
216         ent_optable_indef_div[NEG_INFINITY][NEG_INFINITY] = NOT_A_NUMBER;
217         ent_optable_indef_div[NEG_INFINITY][COMPLEX_INFINITY] =
218                 COMPLEX_INFINITY;
219
220         ent_optable_indef_div[COMPLEX_INFINITY][POS_INFINITY] =
221                 COMPLEX_INFINITY;
222         ent_optable_indef_div[COMPLEX_INFINITY][NEG_INFINITY] =
223                 COMPLEX_INFINITY;
224         ent_optable_indef_div[COMPLEX_INFINITY][COMPLEX_INFINITY] =
225                 COMPLEX_INFINITY;
226
227         /* Mod table */
228         ent_optable_indef_rem[POS_INFINITY][POS_INFINITY] = POS_INFINITY;
229         ent_optable_indef_rem[POS_INFINITY][NEG_INFINITY] = NEG_INFINITY;
230         ent_optable_indef_rem[POS_INFINITY][COMPLEX_INFINITY] =
231                 COMPLEX_INFINITY;
232
233         ent_optable_indef_rem[NEG_INFINITY][POS_INFINITY] = NEG_INFINITY;
234         ent_optable_indef_rem[NEG_INFINITY][NEG_INFINITY] = POS_INFINITY;
235         ent_optable_indef_rem[NEG_INFINITY][COMPLEX_INFINITY] =
236                 COMPLEX_INFINITY;
237
238         ent_optable_indef_rem[COMPLEX_INFINITY][POS_INFINITY] =
239                 COMPLEX_INFINITY;
240         ent_optable_indef_rem[COMPLEX_INFINITY][NEG_INFINITY] =
241                 COMPLEX_INFINITY;
242         ent_optable_indef_rem[COMPLEX_INFINITY][COMPLEX_INFINITY] =
243                 COMPLEX_INFINITY;
244
245         /* exponentiation table */
246         ent_optable_indef_pow[POS_INFINITY][POS_INFINITY] = NOT_A_NUMBER;
247         ent_optable_indef_pow[POS_INFINITY][NEG_INFINITY] = NOT_A_NUMBER;
248         ent_optable_indef_pow[POS_INFINITY][COMPLEX_INFINITY] =
249                 COMPLEX_INFINITY;
250
251         ent_optable_indef_pow[NEG_INFINITY][POS_INFINITY] = NOT_A_NUMBER;
252         ent_optable_indef_pow[NEG_INFINITY][NEG_INFINITY] = NOT_A_NUMBER;
253         ent_optable_indef_pow[NEG_INFINITY][COMPLEX_INFINITY] =
254                 COMPLEX_INFINITY;
255
256         ent_optable_indef_pow[COMPLEX_INFINITY][POS_INFINITY] =
257                 COMPLEX_INFINITY;
258         ent_optable_indef_pow[COMPLEX_INFINITY][NEG_INFINITY] =
259                 COMPLEX_INFINITY;
260         ent_optable_indef_pow[COMPLEX_INFINITY][COMPLEX_INFINITY] =
261                 COMPLEX_INFINITY;
262 }
263
264 #define INDEF_AUTOOPERATE(op, l1, l2)                                   \
265         make_indef(ent_optable_indef_##op[XINDEF_DATA(l1)][XINDEF_DATA(l2)])
266
267 static Lisp_Object indef_negate(Lisp_Object ind)
268 {
269         if (XINDEF_DATA(ind) == POS_INFINITY) {
270                 return make_indef(NEG_INFINITY);
271         } else if (XINDEF_DATA(ind) == NEG_INFINITY) {
272                 return make_indef(POS_INFINITY);
273         } else if (XINDEF_DATA(ind) == COMPLEX_INFINITY) {
274                 return ind;
275         } else {
276                 return make_indef(NOT_A_NUMBER);
277         }
278 }
279
280 static Lisp_Object
281 indef_sum(Lisp_Object l, Lisp_Object r)
282 {
283         if (INDEFP(l) && INDEFP(r))
284                 return INDEF_AUTOOPERATE(sum, l, r);
285
286         if (INDEFP(l) && NUMBERP(r))
287                 return l;
288         else if (NUMBERP(l) && INDEFP(r))
289                 return r;
290         else
291                 return make_indef(NOT_A_NUMBER);
292 }
293 static Lisp_Object
294 indef_diff(Lisp_Object l, Lisp_Object r)
295 {
296         if (INDEFP(l) && INDEFP(r))
297                 return INDEF_AUTOOPERATE(diff, l, r);
298
299         if (INDEFP(l) && NUMBERP(r))
300                 return l;
301         else if (NUMBERP(l) && INDEFP(r))
302                 return indef_negate(r);
303         else
304                 return make_indef(NOT_A_NUMBER);
305 }
306 static Lisp_Object
307 indef_prod(Lisp_Object l, Lisp_Object r)
308 {
309         if (INDEFP(l) && INDEFP(r))
310                 return INDEF_AUTOOPERATE(prod, l, r);
311
312         if (INDEFP(l) && COMPARABLEP(r)) {
313                 if (!NILP(Fzerop(r)))
314                         return make_indef(NOT_A_NUMBER);
315                 else if (!NILP(Fnonnegativep(r)))
316                         return l;
317                 else
318                         return indef_negate(l);
319         } else if (COMPARABLEP(l) && INDEFP(r)) {
320                 if (!NILP(Fzerop(l)))
321                         return make_indef(NOT_A_NUMBER);
322                 else if (!NILP(Fnonnegativep(l)))
323                         return r;
324                 else
325                         return indef_negate(r);
326         } else if (INFINITYP(l) || INFINITYP(r)) {
327                 return make_indef(COMPLEX_INFINITY);
328         } else {
329                 return make_indef(NOT_A_NUMBER);
330         }
331 }
332 static Lisp_Object
333 indef_div(Lisp_Object l, Lisp_Object r)
334 {
335         if (INDEFP(l) && INDEFP(r))
336                 return INDEF_AUTOOPERATE(div, l, r);
337
338         if (INDEFP(l) && COMPARABLEP(r)) {
339                 if (!NILP(Fzerop(r)))
340                         return make_indef(NOT_A_NUMBER);
341                 else if (!NILP(Fnonnegativep(r)))
342                         return l;
343                 else
344                         return indef_negate(l);
345         } else if (COMPARABLEP(l) && INDEFP(r)) {
346                 if (!COMPARABLE_INDEF_P(r))
347                         return r;
348                 else
349                         return Qzero;
350         } else if (INFINITYP(l) || INFINITYP(r)) {
351                 return make_indef(COMPLEX_INFINITY);
352         } else {
353                 return make_indef(NOT_A_NUMBER);
354         }
355 }
356 static Lisp_Object
357 indef_inv(Lisp_Object l)
358 {
359         switch (XINDEF_DATA(l)) {
360         case POS_INFINITY:
361                 return Qzero;
362         case NEG_INFINITY:
363                 return Qzero;
364         case COMPLEX_INFINITY:
365         case NOT_A_NUMBER:
366                 return l;
367
368         case END_OF_COMPARABLE_INFINITIES:
369         case END_OF_INFINITIES:
370         case NUMBER_INDEFS:
371         default:
372                 abort();        /* punishment enough? */
373                 break;
374         }
375         return l;
376 }
377
378 static Lisp_Object
379 indef_rem(Lisp_Object l, Lisp_Object r)
380 {
381         if (INDEFP(l) && INDEFP(r))
382                 return INDEF_AUTOOPERATE(rem, l, r);
383
384         if (INDEFP(l) && COMPARABLEP(r)) {
385                 return make_indef(NOT_A_NUMBER);
386         } else if (COMPARABLEP(l) && INFINITYP(r)) {
387                 return l;
388         } else if (COMPARABLEP(l) && NOT_A_NUMBER_P(r)) {
389                 return r;
390         } else if (INFINITE_POINT_P(r)) {
391                 return l;
392         } else
393                 return make_indef(NOT_A_NUMBER);
394 }
395
396 static Lisp_Object
397 indef_pow(Lisp_Object l, Lisp_Object r)
398 {
399         if (INDEFP(l) && INDEFP(r))
400                 return INDEF_AUTOOPERATE(pow, l, r);
401
402         if (INDEFP(l) && !NILP(Fzerop(r))) {
403                 return make_indef(NOT_A_NUMBER);
404         } else if (COMPARABLE_INDEF_P(l) && COMPARABLEP(r)) {
405                 if (!NILP(Fzerop(r)))
406                         return make_indef(NOT_A_NUMBER);
407                 else if (NILP(Fnonnegativep(r)))
408                         return Qzero;
409                 else if (XINDEF_DATA(l) == NEG_INFINITY &&
410                          !NILP(Fevenp(r)))
411                         return make_indef(POS_INFINITY);
412                 else
413                         return l;
414         } else if (INDEFP(l) && COMPARABLEP(r)) {
415                 return l;
416         } else if (INFINITE_POINT_P(l)) {
417                 return make_indef(COMPLEX_INFINITY);
418         } else if (INDEFP(l)) {
419                 return make_indef(NOT_A_NUMBER);
420         } else if (COMPARABLEP(l) && COMPARABLE_INDEF_P(r)) {
421                 Lisp_Object comp[3] = {make_int(-1), l, make_int(1)};
422                 if (ent_unrel(ASE_UNARY_REL_ONEP, l))   /* l == 1 */
423                         return l;
424                 else if (ent_binrel_transitive_many(
425                                  ASE_BINARY_REL_LESSP, 3, comp))
426                         /* -1 < l < 1 */
427                         return make_int(0);
428                 else if (ent_binrel(ASE_BINARY_REL_LESSP, Qone, l)) {
429                         /* 1 < l */
430                         if (XINDEF_DATA(r) == POS_INFINITY)
431                                 return r;
432                         else
433                                 return Qzero;
434                 } else
435                         return make_indef(NOT_A_NUMBER);
436         } else if (COMPARABLEP(l) && INFINITYP(r)) {
437                 return make_indef(COMPLEX_INFINITY);
438         } else
439                 return make_indef(NOT_A_NUMBER);
440 }
441
442 static inline int
443 indef_eq(Lisp_Object l1, Lisp_Object l2)
444 {
445         if (INDEFP(l1) && INDEFP(l2) &&
446             INFINITYP(l1) && INFINITYP(l2))
447                 return (XINDEF_DATA(l1) == XINDEF_DATA(l2));
448         else if (!COMPARABLEP(l1) || !COMPARABLEP(l2)) {
449                 Fsignal(Qrelation_error, list2(l1, l2));
450                 return Qnil;
451         } else
452                 return 0;
453 }
454
455 static inline int
456 indef_neq(Lisp_Object l1, Lisp_Object l2)
457 {
458         return !(indef_eq(l1, l2));
459 }
460
461 static int
462 indef_lt(Lisp_Object l1, Lisp_Object l2)
463 {
464         if (!COMPARABLEP(l1) || !COMPARABLEP(l2)) {
465                 Fsignal(Qrelation_error, list2(l1, l2));
466                 return Qnil;
467         }
468
469         if (INDEFP(l1) && INDEFP(l2)) {
470                 /* only +infinity is not less than -infinity */
471                 if ((XINDEF_DATA(l1) == POS_INFINITY) &&
472                     (XINDEF_DATA(l2) == NEG_INFINITY))
473                         return (0 == 1);
474                 else
475                         return (0 == 0);
476         } else if (!INDEFP(l1)) {
477                 if (XINDEF_DATA(l2) == NEG_INFINITY)
478                         return (0 == 1);
479                 else
480                         return (0 == 0);
481         } else if (!INDEFP(l2)) {
482                 if (XINDEF_DATA(l1) == POS_INFINITY)
483                         return (0 == 1);
484                 else
485                         return (0 == 0);
486         } else
487                 return wrong_type_argument(Qindefinitep, l1);
488 }
489
490 #if 0
491 static int
492 indef_le(Lisp_Object l1, Lisp_Object l2)
493 {
494         if (!COMPARABLEP(l1) || !COMPARABLEP(l2)) {
495                 Fsignal(Qrelation_error, list2(l1, l2));
496                 return Qnil;
497         }
498
499         if (INDEFP(l1) && INDEFP(l2)) {
500                 /* only +infinity is not leq -infinity */
501                 if ((XINDEF_DATA(l1) == POS_INFINITY) &&
502                     (XINDEF_DATA(l2) == NEG_INFINITY))
503                         return (0 == 1);
504                 else
505                         return (0 == 0);
506         } else if (!INDEFP(l1)) {
507                 if (XINDEF_DATA(l2) == NEG_INFINITY)
508                         return (0 == 1);
509                 else
510                         return (0 == 0);
511         } else if (!INDEFP(l2)) {
512                 if (XINDEF_DATA(l1) == POS_INFINITY)
513                         return (0 == 1);
514                 else
515                         return (0 == 0);
516         } else
517                 return wrong_type_argument(Qindefinitep, l1);
518 }
519 #endif
520
521 static int
522 indef_gt(Lisp_Object l1, Lisp_Object l2)
523 {
524         if (!COMPARABLEP(l1) || !COMPARABLEP(l2)) {
525                 Fsignal(Qrelation_error, list2(l1, l2));
526                 return Qnil;
527         }
528
529         if (INDEFP(l1) && INDEFP(l2)) {
530                 /* only -infinity is not greater than +infinity */
531                 if ((XINDEF_DATA(l1) == NEG_INFINITY) &&
532                     (XINDEF_DATA(l2) == POS_INFINITY))
533                         return (0 == 1);
534                 else
535                         return (0 == 0);
536         } else if (!INDEFP(l1)) {
537                 if (XINDEF_DATA(l2) == POS_INFINITY)
538                         return (0 == 1);
539                 else
540                         return (0 == 0);
541         } else if (!INDEFP(l2)) {
542                 if (XINDEF_DATA(l1) == NEG_INFINITY)
543                         return (0 == 1);
544                 else
545                         return (0 == 0);
546         } else
547                 return wrong_type_argument(Qindefinitep, l1);
548 }
549
550 #if 0
551 static int
552 indef_ge(Lisp_Object l1, Lisp_Object l2)
553 {
554         if (!COMPARABLEP(l1) || !COMPARABLEP(l2)) {
555                 Fsignal(Qrelation_error, list2(l1, l2));
556                 return Qnil;
557         }
558
559         if (INDEFP(l1) && INDEFP(l2)) {
560                 /* only -infinity is not geq +infinity */
561                 if ((XINDEF_DATA(l1) == NEG_INFINITY) &&
562                     (XINDEF_DATA(l2) == POS_INFINITY))
563                         return (0 == 1);
564                 else
565                         return (0 == 0);
566         } else if (!INDEFP(l1)) {
567                 if (XINDEF_DATA(l2) == POS_INFINITY)
568                         return (0 == 1);
569                 else
570                         return (0 == 0);
571         } else if (!INDEFP(l2)) {
572                 if (XINDEF_DATA(l1) == NEG_INFINITY)
573                         return (0 == 1);
574                 else
575                         return (0 == 0);
576         } else
577                 return wrong_type_argument(Qindefinitep, l1);
578 }
579 #endif
580
581 static inline int
582 ent_indef_neutralp(Lisp_Object unused)
583 {
584         return 0;
585 }
586
587 \f
588 static inline void
589 ent_indef_nullary_optable_init(void)
590 {
591         ent_nullop_register(ASE_NULLARY_OP_ZERO, INDEF_T, Qzero);
592         ent_nullop_register(ASE_NULLARY_OP_ONE, INDEF_T, Qone);
593 }
594
595 static inline void
596 ent_indef_unary_optable_init(void)
597 {
598         ent_unop_register(ASE_UNARY_OP_NEG, INDEF_T, indef_negate);
599         ent_unop_register(ASE_UNARY_OP_INV, INDEF_T, indef_inv);
600 }
601
602 static inline void
603 ent_indef_binary_optable_init(void)
604 {
605         ase_object_type_t i;
606
607         for (i = 0; i < ASE_OPTABLE_SIZE; i++) {
608                 ent_binop_register(ASE_BINARY_OP_SUM, i, INDEF_T, indef_sum);
609                 ent_binop_register(ASE_BINARY_OP_SUM, INDEF_T, i, indef_sum);
610                 ent_binop_register(ASE_BINARY_OP_DIFF, i, INDEF_T, indef_diff);
611                 ent_binop_register(ASE_BINARY_OP_DIFF, INDEF_T, i, indef_diff);
612                 ent_binop_register(ASE_BINARY_OP_PROD, i, INDEF_T, indef_prod);
613                 ent_binop_register(ASE_BINARY_OP_PROD, INDEF_T, i, indef_prod);
614                 ent_binop_register(ASE_BINARY_OP_DIV, i, INDEF_T, indef_div);
615                 ent_binop_register(ASE_BINARY_OP_DIV, INDEF_T, i, indef_div);
616                 ent_binop_register(ASE_BINARY_OP_QUO, i, INDEF_T, indef_div);
617                 ent_binop_register(ASE_BINARY_OP_QUO, INDEF_T, i, indef_div);
618                 ent_binop_register(ASE_BINARY_OP_REM, i, INDEF_T, indef_rem);
619                 ent_binop_register(ASE_BINARY_OP_REM, INDEF_T, i, indef_rem);
620                 ent_binop_register(ASE_BINARY_OP_POW, i, INDEF_T, indef_pow);
621                 ent_binop_register(ASE_BINARY_OP_POW, INDEF_T, i, indef_pow);
622         }
623 }
624
625 static inline void
626 ent_indef_unary_reltable_init(void)
627 {
628         ent_unrel_register(ASE_UNARY_REL_ZEROP, INDEF_T, ent_indef_neutralp);
629         ent_unrel_register(ASE_UNARY_REL_ONEP, INDEF_T, ent_indef_neutralp);
630 }
631
632 static inline void
633 ent_indef_binary_reltable_init(void)
634 {
635         ase_object_type_t idx = INDEF_T, i;
636
637         for (i = 0; i < ASE_OPTABLE_SIZE; i++) {
638                 ent_binrel_register(ASE_BINARY_REL_LESSP, i, idx, indef_lt);
639                 ent_binrel_register(ASE_BINARY_REL_LESSP, idx, i, indef_lt);
640                 ent_binrel_register(ASE_BINARY_REL_GREATERP, i, idx, indef_gt);
641                 ent_binrel_register(ASE_BINARY_REL_GREATERP, idx, i, indef_gt);
642                 ent_binrel_register(ASE_BINARY_REL_EQUALP, i, idx, indef_eq);
643                 ent_binrel_register(ASE_BINARY_REL_EQUALP, idx, i, indef_eq);
644                 ent_binrel_register(ASE_BINARY_REL_NEQP, i, idx, indef_neq);
645                 ent_binrel_register(ASE_BINARY_REL_NEQP, idx, i, indef_neq);
646         }
647 }
648
649 static inline void
650 ent_indef_lifttable_init(void)
651 {
652         ase_object_type_t i;
653         for (i = 0; i < ASE_OPTABLE_SIZE; i++) {
654                 ent_lift_register(INDEF_T, i, ent_lift_indef);
655         }
656
657 }
658
659 void init_optables_INDEF_T(void)
660 {
661         ent_indef_nullary_optable_init();
662         ent_indef_unary_optable_init();
663         ent_indef_binary_optable_init();
664         ent_indef_unary_reltable_init();
665         ent_indef_binary_reltable_init();
666         ent_indef_lifttable_init();
667 }
668
669 void init_ent_indef(void)
670 {
671         init_indef_table();
672 }
673
674 void syms_of_ent_indef(void)
675 {
676         INIT_LRECORD_IMPLEMENTATION(indef);
677 }
678
679 void vars_of_ent_indef(void)
680 {
681 /* Now define +infinity and -infinity, complex-infinity and not-a-number */
682         Vnot_a_number = make_indef_internal((indef)NOT_A_NUMBER);
683         Vninfinity = make_indef_internal((indef)NEG_INFINITY);
684         Vpinfinity = make_indef_internal((indef)POS_INFINITY);
685         Vcomplex_infinity = make_indef_internal((indef)COMPLEX_INFINITY);
686
687         DEFVAR_CONST_LISP("not-a-number", &Vnot_a_number /*
688 Not a number.
689 */);
690         DEFVAR_CONST_LISP("+infinity", &Vpinfinity /*
691 Positive infinity.
692 */);
693         DEFVAR_CONST_LISP("-infinity", &Vninfinity /*
694 Negative infinity.
695 */);
696         DEFVAR_CONST_LISP("complex-infinity", &Vcomplex_infinity /*
697 The infinitely distant point in the complex plane.
698 */);
699
700         staticpro(&Vnot_a_number);
701         staticpro(&Vninfinity);
702         staticpro(&Vpinfinity);
703         staticpro(&Vcomplex_infinity);
704
705         Fprovide(intern("indefinite"));
706         Fprovide(intern("infinity"));
707 }
708
709 /* ent-indef.c ends here */