aboutsummaryrefslogtreecommitdiffstats
path: root/src/data.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/data.c')
-rw-r--r--src/data.c157
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
2645Lisp_Object
2646intbig_to_lisp (intmax_t i)
2647{
2648 return INTBIG_TO_LISP (i, INTMAX_MIN);
2649}
2650
2651Lisp_Object
2652uintbig_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. */
2661uintmax_t 2638uintmax_t
2662cons_to_unsigned (Lisp_Object c, uintmax_t max) 2639cons_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. */
2715intmax_t 2709intmax_t
2716cons_to_signed (Lisp_Object c, intmax_t min, intmax_t max) 2710cons_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