diff options
Diffstat (limited to 'src/data.c')
| -rw-r--r-- | src/data.c | 157 |
1 files changed, 82 insertions, 75 deletions
diff --git a/src/data.c b/src/data.c index ece76a5bc6f..6afda1e6fb9 100644 --- a/src/data.c +++ b/src/data.c | |||
| @@ -1132,7 +1132,7 @@ store_symval_forwarding (union Lisp_Fwd *valcontents, register Lisp_Object newva | |||
| 1132 | else if ((prop = Fget (predicate, Qrange), !NILP (prop))) | 1132 | else if ((prop = Fget (predicate, Qrange), !NILP (prop))) |
| 1133 | { | 1133 | { |
| 1134 | Lisp_Object min = XCAR (prop), max = XCDR (prop); | 1134 | Lisp_Object min = XCAR (prop), max = XCDR (prop); |
| 1135 | if (! FIXED_OR_FLOATP (newval) | 1135 | if (! NUMBERP (newval) |
| 1136 | || NILP (CALLN (Fleq, min, newval, max))) | 1136 | || NILP (CALLN (Fleq, min, newval, max))) |
| 1137 | wrong_range (min, max, newval); | 1137 | wrong_range (min, max, newval); |
| 1138 | } | 1138 | } |
| @@ -2627,48 +2627,21 @@ DEFUN ("/=", Fneq, Sneq, 2, 2, 0, | |||
| 2627 | return arithcompare (num1, num2, ARITH_NOTEQUAL); | 2627 | return arithcompare (num1, num2, ARITH_NOTEQUAL); |
| 2628 | } | 2628 | } |
| 2629 | 2629 | ||
| 2630 | /* Convert the integer I to a cons-of-integers, where I is not in | ||
| 2631 | fixnum range. */ | ||
| 2632 | |||
| 2633 | #define INTBIG_TO_LISP(i, extremum) \ | ||
| 2634 | (eassert (FIXNUM_OVERFLOW_P (i)), \ | ||
| 2635 | (! (FIXNUM_OVERFLOW_P ((extremum) >> 16) \ | ||
| 2636 | && FIXNUM_OVERFLOW_P ((i) >> 16)) \ | ||
| 2637 | ? Fcons (make_fixnum ((i) >> 16), make_fixnum ((i) & 0xffff)) \ | ||
| 2638 | : ! (FIXNUM_OVERFLOW_P ((extremum) >> 16 >> 24) \ | ||
| 2639 | && FIXNUM_OVERFLOW_P ((i) >> 16 >> 24)) \ | ||
| 2640 | ? Fcons (make_fixnum ((i) >> 16 >> 24), \ | ||
| 2641 | Fcons (make_fixnum ((i) >> 16 & 0xffffff), \ | ||
| 2642 | make_fixnum ((i) & 0xffff))) \ | ||
| 2643 | : make_float (i))) | ||
| 2644 | |||
| 2645 | Lisp_Object | ||
| 2646 | intbig_to_lisp (intmax_t i) | ||
| 2647 | { | ||
| 2648 | return INTBIG_TO_LISP (i, INTMAX_MIN); | ||
| 2649 | } | ||
| 2650 | |||
| 2651 | Lisp_Object | ||
| 2652 | uintbig_to_lisp (uintmax_t i) | ||
| 2653 | { | ||
| 2654 | return INTBIG_TO_LISP (i, UINTMAX_MAX); | ||
| 2655 | } | ||
| 2656 | |||
| 2657 | /* Convert the cons-of-integers, integer, or float value C to an | 2630 | /* Convert the cons-of-integers, integer, or float value C to an |
| 2658 | unsigned value with maximum value MAX, where MAX is one less than a | 2631 | unsigned value with maximum value MAX, where MAX is one less than a |
| 2659 | power of 2. Signal an error if C does not have a valid format or | 2632 | power of 2. Signal an error if C does not have a valid format or |
| 2660 | is out of range. */ | 2633 | is out of range. |
| 2634 | |||
| 2635 | Although Emacs represents large integers with bignums instead of | ||
| 2636 | cons-of-integers or floats, for now this function still accepts the | ||
| 2637 | obsolete forms in case some old Lisp code still generates them. */ | ||
| 2661 | uintmax_t | 2638 | uintmax_t |
| 2662 | cons_to_unsigned (Lisp_Object c, uintmax_t max) | 2639 | cons_to_unsigned (Lisp_Object c, uintmax_t max) |
| 2663 | { | 2640 | { |
| 2664 | bool valid = false; | 2641 | bool valid = false; |
| 2665 | uintmax_t val UNINIT; | 2642 | uintmax_t val UNINIT; |
| 2666 | if (FIXNUMP (c)) | 2643 | |
| 2667 | { | 2644 | if (FLOATP (c)) |
| 2668 | valid = XFIXNUM (c) >= 0; | ||
| 2669 | val = XFIXNUM (c); | ||
| 2670 | } | ||
| 2671 | else if (FLOATP (c)) | ||
| 2672 | { | 2645 | { |
| 2673 | double d = XFLOAT_DATA (c); | 2646 | double d = XFLOAT_DATA (c); |
| 2674 | if (d >= 0 && d < 1.0 + max) | 2647 | if (d >= 0 && d < 1.0 + max) |
| @@ -2677,27 +2650,44 @@ cons_to_unsigned (Lisp_Object c, uintmax_t max) | |||
| 2677 | valid = val == d; | 2650 | valid = val == d; |
| 2678 | } | 2651 | } |
| 2679 | } | 2652 | } |
| 2680 | else if (CONSP (c) && FIXNATP (XCAR (c))) | 2653 | else |
| 2681 | { | 2654 | { |
| 2682 | uintmax_t top = XFIXNAT (XCAR (c)); | 2655 | Lisp_Object hi = CONSP (c) ? XCAR (c) : c; |
| 2683 | Lisp_Object rest = XCDR (c); | 2656 | |
| 2684 | if (top <= UINTMAX_MAX >> 24 >> 16 | 2657 | if (FIXNUMP (hi)) |
| 2685 | && CONSP (rest) | ||
| 2686 | && FIXNATP (XCAR (rest)) && XFIXNAT (XCAR (rest)) < 1 << 24 | ||
| 2687 | && FIXNATP (XCDR (rest)) && XFIXNAT (XCDR (rest)) < 1 << 16) | ||
| 2688 | { | 2658 | { |
| 2689 | uintmax_t mid = XFIXNAT (XCAR (rest)); | 2659 | val = XFIXNUM (hi); |
| 2690 | val = top << 24 << 16 | mid << 16 | XFIXNAT (XCDR (rest)); | 2660 | valid = 0 <= val; |
| 2691 | valid = true; | ||
| 2692 | } | 2661 | } |
| 2693 | else if (top <= UINTMAX_MAX >> 16) | 2662 | else |
| 2694 | { | 2663 | { |
| 2695 | if (CONSP (rest)) | 2664 | val = bignum_to_uintmax (hi); |
| 2696 | rest = XCAR (rest); | 2665 | valid = val != 0; |
| 2697 | if (FIXNATP (rest) && XFIXNAT (rest) < 1 << 16) | 2666 | } |
| 2667 | |||
| 2668 | if (valid && CONSP (c)) | ||
| 2669 | { | ||
| 2670 | uintmax_t top = val; | ||
| 2671 | Lisp_Object rest = XCDR (c); | ||
| 2672 | if (top <= UINTMAX_MAX >> 24 >> 16 | ||
| 2673 | && CONSP (rest) | ||
| 2674 | && FIXNATP (XCAR (rest)) && XFIXNAT (XCAR (rest)) < 1 << 24 | ||
| 2675 | && FIXNATP (XCDR (rest)) && XFIXNAT (XCDR (rest)) < 1 << 16) | ||
| 2698 | { | 2676 | { |
| 2699 | val = top << 16 | XFIXNAT (rest); | 2677 | uintmax_t mid = XFIXNAT (XCAR (rest)); |
| 2700 | valid = true; | 2678 | val = top << 24 << 16 | mid << 16 | XFIXNAT (XCDR (rest)); |
| 2679 | } | ||
| 2680 | else | ||
| 2681 | { | ||
| 2682 | valid = top <= UINTMAX_MAX >> 16; | ||
| 2683 | if (valid) | ||
| 2684 | { | ||
| 2685 | if (CONSP (rest)) | ||
| 2686 | rest = XCAR (rest); | ||
| 2687 | valid = FIXNATP (rest) && XFIXNAT (rest) < 1 << 16; | ||
| 2688 | if (valid) | ||
| 2689 | val = top << 16 | XFIXNAT (rest); | ||
| 2690 | } | ||
| 2701 | } | 2691 | } |
| 2702 | } | 2692 | } |
| 2703 | } | 2693 | } |
| @@ -2711,18 +2701,18 @@ cons_to_unsigned (Lisp_Object c, uintmax_t max) | |||
| 2711 | value with extrema MIN and MAX. MAX should be one less than a | 2701 | value with extrema MIN and MAX. MAX should be one less than a |
| 2712 | power of 2, and MIN should be zero or the negative of a power of 2. | 2702 | power of 2, and MIN should be zero or the negative of a power of 2. |
| 2713 | Signal an error if C does not have a valid format or is out of | 2703 | Signal an error if C does not have a valid format or is out of |
| 2714 | range. */ | 2704 | range. |
| 2705 | |||
| 2706 | Although Emacs represents large integers with bignums instead of | ||
| 2707 | cons-of-integers or floats, for now this function still accepts the | ||
| 2708 | obsolete forms in case some old Lisp code still generates them. */ | ||
| 2715 | intmax_t | 2709 | intmax_t |
| 2716 | cons_to_signed (Lisp_Object c, intmax_t min, intmax_t max) | 2710 | cons_to_signed (Lisp_Object c, intmax_t min, intmax_t max) |
| 2717 | { | 2711 | { |
| 2718 | bool valid = false; | 2712 | bool valid = false; |
| 2719 | intmax_t val UNINIT; | 2713 | intmax_t val UNINIT; |
| 2720 | if (FIXNUMP (c)) | 2714 | |
| 2721 | { | 2715 | if (FLOATP (c)) |
| 2722 | val = XFIXNUM (c); | ||
| 2723 | valid = true; | ||
| 2724 | } | ||
| 2725 | else if (FLOATP (c)) | ||
| 2726 | { | 2716 | { |
| 2727 | double d = XFLOAT_DATA (c); | 2717 | double d = XFLOAT_DATA (c); |
| 2728 | if (d >= min && d < 1.0 + max) | 2718 | if (d >= min && d < 1.0 + max) |
| @@ -2731,27 +2721,44 @@ cons_to_signed (Lisp_Object c, intmax_t min, intmax_t max) | |||
| 2731 | valid = val == d; | 2721 | valid = val == d; |
| 2732 | } | 2722 | } |
| 2733 | } | 2723 | } |
| 2734 | else if (CONSP (c) && FIXNUMP (XCAR (c))) | 2724 | else |
| 2735 | { | 2725 | { |
| 2736 | intmax_t top = XFIXNUM (XCAR (c)); | 2726 | Lisp_Object hi = CONSP (c) ? XCAR (c) : c; |
| 2737 | Lisp_Object rest = XCDR (c); | 2727 | |
| 2738 | if (top >= INTMAX_MIN >> 24 >> 16 && top <= INTMAX_MAX >> 24 >> 16 | 2728 | if (FIXNUMP (hi)) |
| 2739 | && CONSP (rest) | ||
| 2740 | && FIXNATP (XCAR (rest)) && XFIXNAT (XCAR (rest)) < 1 << 24 | ||
| 2741 | && FIXNATP (XCDR (rest)) && XFIXNAT (XCDR (rest)) < 1 << 16) | ||
| 2742 | { | 2729 | { |
| 2743 | intmax_t mid = XFIXNAT (XCAR (rest)); | 2730 | val = XFIXNUM (hi); |
| 2744 | val = top << 24 << 16 | mid << 16 | XFIXNAT (XCDR (rest)); | ||
| 2745 | valid = true; | 2731 | valid = true; |
| 2746 | } | 2732 | } |
| 2747 | else if (top >= INTMAX_MIN >> 16 && top <= INTMAX_MAX >> 16) | 2733 | else if (BIGNUMP (hi)) |
| 2748 | { | 2734 | { |
| 2749 | if (CONSP (rest)) | 2735 | val = bignum_to_intmax (hi); |
| 2750 | rest = XCAR (rest); | 2736 | valid = val != 0; |
| 2751 | if (FIXNATP (rest) && XFIXNAT (rest) < 1 << 16) | 2737 | } |
| 2738 | |||
| 2739 | if (valid && CONSP (c)) | ||
| 2740 | { | ||
| 2741 | intmax_t top = val; | ||
| 2742 | Lisp_Object rest = XCDR (c); | ||
| 2743 | if (top >= INTMAX_MIN >> 24 >> 16 && top <= INTMAX_MAX >> 24 >> 16 | ||
| 2744 | && CONSP (rest) | ||
| 2745 | && FIXNATP (XCAR (rest)) && XFIXNAT (XCAR (rest)) < 1 << 24 | ||
| 2746 | && FIXNATP (XCDR (rest)) && XFIXNAT (XCDR (rest)) < 1 << 16) | ||
| 2747 | { | ||
| 2748 | intmax_t mid = XFIXNAT (XCAR (rest)); | ||
| 2749 | val = top << 24 << 16 | mid << 16 | XFIXNAT (XCDR (rest)); | ||
| 2750 | } | ||
| 2751 | else | ||
| 2752 | { | 2752 | { |
| 2753 | val = top << 16 | XFIXNAT (rest); | 2753 | valid = INTMAX_MIN >> 16 <= top && top <= INTMAX_MAX >> 16; |
| 2754 | valid = true; | 2754 | if (valid) |
| 2755 | { | ||
| 2756 | if (CONSP (rest)) | ||
| 2757 | rest = XCAR (rest); | ||
| 2758 | valid = FIXNATP (rest) && XFIXNAT (rest) < 1 << 16; | ||
| 2759 | if (valid) | ||
| 2760 | val = top << 16 | XFIXNAT (rest); | ||
| 2761 | } | ||
| 2755 | } | 2762 | } |
| 2756 | } | 2763 | } |
| 2757 | } | 2764 | } |
| @@ -2770,11 +2777,11 @@ NUMBER may be an integer or a floating point number. */) | |||
| 2770 | char buffer[max (FLOAT_TO_STRING_BUFSIZE, INT_BUFSIZE_BOUND (EMACS_INT))]; | 2777 | char buffer[max (FLOAT_TO_STRING_BUFSIZE, INT_BUFSIZE_BOUND (EMACS_INT))]; |
| 2771 | int len; | 2778 | int len; |
| 2772 | 2779 | ||
| 2780 | CHECK_NUMBER (number); | ||
| 2781 | |||
| 2773 | if (BIGNUMP (number)) | 2782 | if (BIGNUMP (number)) |
| 2774 | return bignum_to_string (number, 10); | 2783 | return bignum_to_string (number, 10); |
| 2775 | 2784 | ||
| 2776 | CHECK_FIXNUM_OR_FLOAT (number); | ||
| 2777 | |||
| 2778 | if (FLOATP (number)) | 2785 | if (FLOATP (number)) |
| 2779 | len = float_to_string (buffer, XFLOAT_DATA (number)); | 2786 | len = float_to_string (buffer, XFLOAT_DATA (number)); |
| 2780 | else | 2787 | else |