aboutsummaryrefslogtreecommitdiffstats
path: root/src/data.c
diff options
context:
space:
mode:
authorPaul Eggert2018-08-27 21:27:50 -0700
committerPaul Eggert2018-08-27 21:45:22 -0700
commit9abaf5f3581ecb76f30e8a6e7ee0e9633c133d1c (patch)
treec39260a6e26845b0a1307be98b38581468925c58 /src/data.c
parentbf1b147b55e1328efca6e40181e79dd9a369895d (diff)
downloademacs-9abaf5f3581ecb76f30e8a6e7ee0e9633c133d1c.tar.gz
emacs-9abaf5f3581ecb76f30e8a6e7ee0e9633c133d1c.zip
Modularize bignums better
* src/bignum.c, src/bignum.h: New files. Only modules that need to know how bignums are implemented should include bignum.h. Currently these are alloc.c, bignum.c (of course), data.c, emacs.c, emacs-module.c, floatfns.c, fns.c, print.c. * src/Makefile.in (base_obj): Add bignum.o. * src/alloc.c (make_bignum_str): Move to bignum.c. (make_number): Remove; replaced by bignum.c’s make_integer. All callers changed. * src/conf_post.h (ARG_NONNULL): New macro. * src/json.c (json_to_lisp): Use it. * src/data.c (Fnatnump): Move NATNUMP’s implementation here from lisp.h. * src/data.c (Fnumber_to_string): * src/editfns.c (styled_format): Move conversion of string to bignum to bignum_to_string, and call it here. * src/emacs-module.c (module_make_integer): * src/floatfns.c (Fabs): Simplify by using make_int. * src/emacs.c: Include bignum.h, to expand its inline fns. * src/floatfns.c (Ffloat): Simplify by using XFLOATINT. (rounding_driver): Simplify by using double_to_bignum. (rounddiv_q): Clarify use of temporaries. * src/lisp.h: Move decls that need to know bignum internals to bignum.h. Do not include gmp.h or mini-gmp.h; that is now bignum.h’s job. (GMP_NUM_BITS, struct Lisp_Bignum, XBIGNUM, mpz_set_intmax): Move to bignum.h. (make_int): New function. (NATNUMP): Remove; all callers changed to use Fnatnump. (XFLOATINT): If arg is a bignum, use bignum_to_double, so that bignum internals are not exposed here. * src/print.c (print_vectorlike): Use SAFE_ALLOCA to avoid the need for a record_unwind_protect_ptr.
Diffstat (limited to 'src/data.c')
-rw-r--r--src/data.c38
1 files changed, 17 insertions, 21 deletions
diff --git a/src/data.c b/src/data.c
index 170a74a6589..ece76a5bc6f 100644
--- a/src/data.c
+++ b/src/data.c
@@ -29,6 +29,7 @@ along with GNU Emacs. If not, see <https://www.gnu.org/licenses/>. */
29#include <intprops.h> 29#include <intprops.h>
30 30
31#include "lisp.h" 31#include "lisp.h"
32#include "bignum.h"
32#include "puresize.h" 33#include "puresize.h"
33#include "character.h" 34#include "character.h"
34#include "buffer.h" 35#include "buffer.h"
@@ -525,9 +526,9 @@ DEFUN ("natnump", Fnatnump, Snatnump, 1, 1, 0,
525 attributes: const) 526 attributes: const)
526 (Lisp_Object object) 527 (Lisp_Object object)
527{ 528{
528 if (NATNUMP (object)) 529 return ((FIXNUMP (object) ? 0 <= XFIXNUM (object)
529 return Qt; 530 : BIGNUMP (object) && 0 <= mpz_sgn (XBIGNUM (object)->value))
530 return Qnil; 531 ? Qt : Qnil);
531} 532}
532 533
533DEFUN ("numberp", Fnumberp, Snumberp, 1, 1, 0, 534DEFUN ("numberp", Fnumberp, Snumberp, 1, 1, 0,
@@ -2400,7 +2401,7 @@ emacs_mpz_size (mpz_t const op)
2400 the library code aborts when a number is too large. These wrappers 2401 the library code aborts when a number is too large. These wrappers
2401 avoid the problem for functions that can return numbers much larger 2402 avoid the problem for functions that can return numbers much larger
2402 than their arguments. For slowly-growing numbers, the integer 2403 than their arguments. For slowly-growing numbers, the integer
2403 width check in make_number should suffice. */ 2404 width checks in bignum.c should suffice. */
2404 2405
2405static void 2406static void
2406emacs_mpz_mul (mpz_t rop, mpz_t const op1, mpz_t const op2) 2407emacs_mpz_mul (mpz_t rop, mpz_t const op1, mpz_t const op2)
@@ -2770,12 +2771,7 @@ NUMBER may be an integer or a floating point number. */)
2770 int len; 2771 int len;
2771 2772
2772 if (BIGNUMP (number)) 2773 if (BIGNUMP (number))
2773 { 2774 return bignum_to_string (number, 10);
2774 ptrdiff_t count = SPECPDL_INDEX ();
2775 char *str = mpz_get_str (NULL, 10, XBIGNUM (number)->value);
2776 record_unwind_protect_ptr (xfree, str);
2777 return unbind_to (count, make_unibyte_string (str, strlen (str)));
2778 }
2779 2775
2780 CHECK_FIXNUM_OR_FLOAT (number); 2776 CHECK_FIXNUM_OR_FLOAT (number);
2781 2777
@@ -3011,7 +3007,7 @@ arith_driver (enum arithop code, ptrdiff_t nargs, Lisp_Object *args)
3011 } 3007 }
3012 } 3008 }
3013 3009
3014 return unbind_to (count, make_number (accum)); 3010 return unbind_to (count, make_integer (accum));
3015} 3011}
3016 3012
3017static Lisp_Object 3013static Lisp_Object
@@ -3141,7 +3137,7 @@ Both must be integers or markers. */)
3141 3137
3142 mpz_init (result); 3138 mpz_init (result);
3143 mpz_tdiv_r (result, *xmp, *ymp); 3139 mpz_tdiv_r (result, *xmp, *ymp);
3144 val = make_number (result); 3140 val = make_integer (result);
3145 mpz_clear (result); 3141 mpz_clear (result);
3146 3142
3147 if (xmp == &xm) 3143 if (xmp == &xm)
@@ -3221,7 +3217,7 @@ Both X and Y must be numbers or markers. */)
3221 if (cmpy < 0 ? cmpr > 0 : cmpr < 0) 3217 if (cmpy < 0 ? cmpr > 0 : cmpr < 0)
3222 mpz_add (result, result, *ymp); 3218 mpz_add (result, result, *ymp);
3223 3219
3224 val = make_number (result); 3220 val = make_integer (result);
3225 mpz_clear (result); 3221 mpz_clear (result);
3226 3222
3227 if (xmp == &xm) 3223 if (xmp == &xm)
@@ -3351,7 +3347,7 @@ In this case, the sign bit is duplicated. */)
3351 emacs_mpz_mul_2exp (result, XBIGNUM (value)->value, XFIXNUM (count)); 3347 emacs_mpz_mul_2exp (result, XBIGNUM (value)->value, XFIXNUM (count));
3352 else 3348 else
3353 mpz_fdiv_q_2exp (result, XBIGNUM (value)->value, - XFIXNUM (count)); 3349 mpz_fdiv_q_2exp (result, XBIGNUM (value)->value, - XFIXNUM (count));
3354 val = make_number (result); 3350 val = make_integer (result);
3355 mpz_clear (result); 3351 mpz_clear (result);
3356 } 3352 }
3357 else if (XFIXNUM (count) <= 0) 3353 else if (XFIXNUM (count) <= 0)
@@ -3378,7 +3374,7 @@ In this case, the sign bit is duplicated. */)
3378 else 3374 else
3379 mpz_fdiv_q_2exp (result, result, - XFIXNUM (count)); 3375 mpz_fdiv_q_2exp (result, result, - XFIXNUM (count));
3380 3376
3381 val = make_number (result); 3377 val = make_integer (result);
3382 mpz_clear (result); 3378 mpz_clear (result);
3383 } 3379 }
3384 3380
@@ -3407,7 +3403,7 @@ expt_integer (Lisp_Object x, Lisp_Object y)
3407 ? (mpz_set_intmax (val, XFIXNUM (x)), val) 3403 ? (mpz_set_intmax (val, XFIXNUM (x)), val)
3408 : XBIGNUM (x)->value), 3404 : XBIGNUM (x)->value),
3409 exp); 3405 exp);
3410 Lisp_Object res = make_number (val); 3406 Lisp_Object res = make_integer (val);
3411 mpz_clear (val); 3407 mpz_clear (val);
3412 return res; 3408 return res;
3413} 3409}
@@ -3427,7 +3423,7 @@ Markers are converted to integers. */)
3427 mpz_t num; 3423 mpz_t num;
3428 mpz_init (num); 3424 mpz_init (num);
3429 mpz_add_ui (num, XBIGNUM (number)->value, 1); 3425 mpz_add_ui (num, XBIGNUM (number)->value, 1);
3430 number = make_number (num); 3426 number = make_integer (num);
3431 mpz_clear (num); 3427 mpz_clear (num);
3432 } 3428 }
3433 else 3429 else
@@ -3440,7 +3436,7 @@ Markers are converted to integers. */)
3440 mpz_t num; 3436 mpz_t num;
3441 mpz_init (num); 3437 mpz_init (num);
3442 mpz_set_intmax (num, XFIXNUM (number) + 1); 3438 mpz_set_intmax (num, XFIXNUM (number) + 1);
3443 number = make_number (num); 3439 number = make_integer (num);
3444 mpz_clear (num); 3440 mpz_clear (num);
3445 } 3441 }
3446 } 3442 }
@@ -3462,7 +3458,7 @@ Markers are converted to integers. */)
3462 mpz_t num; 3458 mpz_t num;
3463 mpz_init (num); 3459 mpz_init (num);
3464 mpz_sub_ui (num, XBIGNUM (number)->value, 1); 3460 mpz_sub_ui (num, XBIGNUM (number)->value, 1);
3465 number = make_number (num); 3461 number = make_integer (num);
3466 mpz_clear (num); 3462 mpz_clear (num);
3467 } 3463 }
3468 else 3464 else
@@ -3475,7 +3471,7 @@ Markers are converted to integers. */)
3475 mpz_t num; 3471 mpz_t num;
3476 mpz_init (num); 3472 mpz_init (num);
3477 mpz_set_intmax (num, XFIXNUM (number) - 1); 3473 mpz_set_intmax (num, XFIXNUM (number) - 1);
3478 number = make_number (num); 3474 number = make_integer (num);
3479 mpz_clear (num); 3475 mpz_clear (num);
3480 } 3476 }
3481 } 3477 }
@@ -3492,7 +3488,7 @@ DEFUN ("lognot", Flognot, Slognot, 1, 1, 0,
3492 mpz_t value; 3488 mpz_t value;
3493 mpz_init (value); 3489 mpz_init (value);
3494 mpz_com (value, XBIGNUM (number)->value); 3490 mpz_com (value, XBIGNUM (number)->value);
3495 number = make_number (value); 3491 number = make_integer (value);
3496 mpz_clear (value); 3492 mpz_clear (value);
3497 } 3493 }
3498 else 3494 else