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