aboutsummaryrefslogtreecommitdiffstats
path: root/src/data.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/data.c')
-rw-r--r--src/data.c126
1 files changed, 46 insertions, 80 deletions
diff --git a/src/data.c b/src/data.c
index beff570d552..577ae777d89 100644
--- a/src/data.c
+++ b/src/data.c
@@ -22,9 +22,6 @@ along with GNU Emacs. If not, see <http://www.gnu.org/licenses/>. */
22#include <signal.h> 22#include <signal.h>
23#include <stdio.h> 23#include <stdio.h>
24#include <setjmp.h> 24#include <setjmp.h>
25
26#include <intprops.h>
27
28#include "lisp.h" 25#include "lisp.h"
29#include "puresize.h" 26#include "puresize.h"
30#include "character.h" 27#include "character.h"
@@ -2429,8 +2426,10 @@ static Lisp_Object float_arith_driver (double, size_t, enum arithop,
2429static Lisp_Object 2426static Lisp_Object
2430arith_driver (enum arithop code, size_t nargs, register Lisp_Object *args) 2427arith_driver (enum arithop code, size_t nargs, register Lisp_Object *args)
2431{ 2428{
2429 register Lisp_Object val;
2432 register size_t argnum; 2430 register size_t argnum;
2433 register EMACS_INT accum = 0; 2431 register EMACS_INT accum = 0;
2432 register EMACS_INT next;
2434 2433
2435 switch (SWITCH_ENUM_CAST (code)) 2434 switch (SWITCH_ENUM_CAST (code))
2436 { 2435 {
@@ -2452,89 +2451,58 @@ arith_driver (enum arithop code, size_t nargs, register Lisp_Object *args)
2452 2451
2453 for (argnum = 0; argnum < nargs; argnum++) 2452 for (argnum = 0; argnum < nargs; argnum++)
2454 { 2453 {
2455 EMACS_INT a = accum;
2456 int use_float = 0;
2457
2458 /* Using args[argnum] as argument to CHECK_NUMBER_... */ 2454 /* Using args[argnum] as argument to CHECK_NUMBER_... */
2459 Lisp_Object val = args[argnum]; 2455 val = args[argnum];
2460 CHECK_NUMBER_OR_FLOAT_COERCE_MARKER (val); 2456 CHECK_NUMBER_OR_FLOAT_COERCE_MARKER (val);
2461 args[argnum] = val;
2462 2457
2463 if (FLOATP (val)) 2458 if (FLOATP (val))
2464 use_float = 1; 2459 return float_arith_driver ((double) accum, argnum, code,
2465 else 2460 nargs, args);
2461 args[argnum] = val;
2462 next = XINT (args[argnum]);
2463 switch (SWITCH_ENUM_CAST (code))
2466 { 2464 {
2467 EMACS_INT next = XINT (val); 2465 case Aadd:
2468 switch (SWITCH_ENUM_CAST (code)) 2466 accum += next;
2467 break;
2468 case Asub:
2469 accum = argnum ? accum - next : nargs == 1 ? - next : next;
2470 break;
2471 case Amult:
2472 accum *= next;
2473 break;
2474 case Adiv:
2475 if (!argnum)
2476 accum = next;
2477 else
2469 { 2478 {
2470 case Aadd: 2479 if (next == 0)
2471 if (next < 0 2480 xsignal0 (Qarith_error);
2472 ? a < TYPE_MINIMUM (EMACS_INT) - next 2481 accum /= next;
2473 : TYPE_MAXIMUM (EMACS_INT) - next < a)
2474 use_float = 1;
2475 else
2476 a += next;
2477 break;
2478 case Asub:
2479 if (argnum == 0 && nargs != 1)
2480 a = next;
2481 else if (next < 0
2482 ? TYPE_MAXIMUM (EMACS_INT) + next < a
2483 : a < TYPE_MINIMUM (EMACS_INT) + next)
2484 use_float = 1;
2485 else
2486 a -= next;
2487 break;
2488 case Amult:
2489 if (next < 0
2490 ? (a < 0
2491 ? a < TYPE_MAXIMUM (EMACS_INT) / next
2492 : next != -1 && TYPE_MINIMUM (EMACS_INT) / next < a)
2493 : (next != 0
2494 && (a < 0
2495 ? a < TYPE_MINIMUM (EMACS_INT) / next
2496 : TYPE_MAXIMUM (EMACS_INT) / next < a)))
2497 use_float = 1;
2498 else
2499 a *= next;
2500 break;
2501 case Adiv:
2502 if (!argnum)
2503 a = next;
2504 else
2505 {
2506 if (next == 0)
2507 xsignal0 (Qarith_error);
2508 a /= next;
2509 }
2510 break;
2511 case Alogand:
2512 a &= next;
2513 break;
2514 case Alogior:
2515 a |= next;
2516 break;
2517 case Alogxor:
2518 a ^= next;
2519 break;
2520 case Amax:
2521 if (!argnum || a < next)
2522 a = next;
2523 break;
2524 case Amin:
2525 if (!argnum || next < a)
2526 a = next;
2527 break;
2528 } 2482 }
2483 break;
2484 case Alogand:
2485 accum &= next;
2486 break;
2487 case Alogior:
2488 accum |= next;
2489 break;
2490 case Alogxor:
2491 accum ^= next;
2492 break;
2493 case Amax:
2494 if (!argnum || next > accum)
2495 accum = next;
2496 break;
2497 case Amin:
2498 if (!argnum || next < accum)
2499 accum = next;
2500 break;
2529 } 2501 }
2530
2531 if (use_float)
2532 return float_arith_driver (accum, argnum, code, nargs, args);
2533
2534 accum = a;
2535 } 2502 }
2536 2503
2537 return make_fixnum_or_float (accum); 2504 XSETINT (val, accum);
2505 return val;
2538} 2506}
2539 2507
2540#undef isnan 2508#undef isnan
@@ -2809,8 +2777,7 @@ Markers are converted to integers. */)
2809 2777
2810 if (FLOATP (number)) 2778 if (FLOATP (number))
2811 return (make_float (1.0 + XFLOAT_DATA (number))); 2779 return (make_float (1.0 + XFLOAT_DATA (number)));
2812 if (XINT (number) + 1 == MOST_POSITIVE_FIXNUM + 1) 2780
2813 return make_float (XINT (number) + 1);
2814 XSETINT (number, XINT (number) + 1); 2781 XSETINT (number, XINT (number) + 1);
2815 return number; 2782 return number;
2816} 2783}
@@ -2824,8 +2791,7 @@ Markers are converted to integers. */)
2824 2791
2825 if (FLOATP (number)) 2792 if (FLOATP (number))
2826 return (make_float (-1.0 + XFLOAT_DATA (number))); 2793 return (make_float (-1.0 + XFLOAT_DATA (number)));
2827 if (XINT (number) - 1 == MOST_NEGATIVE_FIXNUM - 1) 2794
2828 return make_float (XINT (number) - 1);
2829 XSETINT (number, XINT (number) - 1); 2795 XSETINT (number, XINT (number) - 1);
2830 return number; 2796 return number;
2831} 2797}