diff options
| author | Tom Tromey | 2018-07-07 15:32:52 -0600 |
|---|---|---|
| committer | Tom Tromey | 2018-07-12 22:12:27 -0600 |
| commit | 1e8ae6ca237e22e11b3db63a01e558ad5a3d6ef3 (patch) | |
| tree | a8fabadc647288ce253d2813b8074c5b903b52b8 | |
| parent | 580d173b9a7db78f6d62972ef8e943d31dde5c9d (diff) | |
| download | emacs-1e8ae6ca237e22e11b3db63a01e558ad5a3d6ef3.tar.gz emacs-1e8ae6ca237e22e11b3db63a01e558ad5a3d6ef3.zip | |
Make the reader accept bignums
* src/data.c (Fstring_to_number): Update.
* src/lisp.h (S2N_OVERFLOW_TO_FLOAT): Remove.
* src/lread.c (free_contents): New function.
(read_integer): Handle bignums.
(read1): Update.
(string_to_number): Handle bignums.
(syms_of_lread): Remove read-integer-overflow-as-float.
* src/process.c (Fsignal_process): Update.
| -rw-r--r-- | src/data.c | 3 | ||||
| -rw-r--r-- | src/lisp.h | 2 | ||||
| -rw-r--r-- | src/lread.c | 66 | ||||
| -rw-r--r-- | src/process.c | 2 |
4 files changed, 35 insertions, 38 deletions
diff --git a/src/data.c b/src/data.c index efcffbbf6ab..8ffed8bbb52 100644 --- a/src/data.c +++ b/src/data.c | |||
| @@ -2727,8 +2727,7 @@ If the base used is not 10, STRING is always parsed as an integer. */) | |||
| 2727 | while (*p == ' ' || *p == '\t') | 2727 | while (*p == ' ' || *p == '\t') |
| 2728 | p++; | 2728 | p++; |
| 2729 | 2729 | ||
| 2730 | int flags = S2N_IGNORE_TRAILING | S2N_OVERFLOW_TO_FLOAT; | 2730 | Lisp_Object val = string_to_number (p, b, S2N_IGNORE_TRAILING); |
| 2731 | Lisp_Object val = string_to_number (p, b, flags); | ||
| 2732 | return NILP (val) ? make_fixnum (0) : val; | 2731 | return NILP (val) ? make_fixnum (0) : val; |
| 2733 | } | 2732 | } |
| 2734 | 2733 | ||
diff --git a/src/lisp.h b/src/lisp.h index 6a3db24949a..be679320494 100644 --- a/src/lisp.h +++ b/src/lisp.h | |||
| @@ -3858,7 +3858,7 @@ LOADHIST_ATTACH (Lisp_Object x) | |||
| 3858 | } | 3858 | } |
| 3859 | extern int openp (Lisp_Object, Lisp_Object, Lisp_Object, | 3859 | extern int openp (Lisp_Object, Lisp_Object, Lisp_Object, |
| 3860 | Lisp_Object *, Lisp_Object, bool); | 3860 | Lisp_Object *, Lisp_Object, bool); |
| 3861 | enum { S2N_IGNORE_TRAILING = 1, S2N_OVERFLOW_TO_FLOAT = 2 }; | 3861 | enum { S2N_IGNORE_TRAILING = 1 }; |
| 3862 | extern Lisp_Object string_to_number (char const *, int, int); | 3862 | extern Lisp_Object string_to_number (char const *, int, int); |
| 3863 | extern void map_obarray (Lisp_Object, void (*) (Lisp_Object, Lisp_Object), | 3863 | extern void map_obarray (Lisp_Object, void (*) (Lisp_Object, Lisp_Object), |
| 3864 | Lisp_Object); | 3864 | Lisp_Object); |
diff --git a/src/lread.c b/src/lread.c index 49fa51d1a80..ff86c96c9b5 100644 --- a/src/lread.c +++ b/src/lread.c | |||
| @@ -2631,6 +2631,13 @@ digit_to_number (int character, int base) | |||
| 2631 | return digit < base ? digit : -1; | 2631 | return digit < base ? digit : -1; |
| 2632 | } | 2632 | } |
| 2633 | 2633 | ||
| 2634 | static void | ||
| 2635 | free_contents (void *p) | ||
| 2636 | { | ||
| 2637 | void **ptr = (void **) p; | ||
| 2638 | xfree (*ptr); | ||
| 2639 | } | ||
| 2640 | |||
| 2634 | /* Read an integer in radix RADIX using READCHARFUN to read | 2641 | /* Read an integer in radix RADIX using READCHARFUN to read |
| 2635 | characters. RADIX must be in the interval [2..36]; if it isn't, a | 2642 | characters. RADIX must be in the interval [2..36]; if it isn't, a |
| 2636 | read error is signaled . Value is the integer read. Signals an | 2643 | read error is signaled . Value is the integer read. Signals an |
| @@ -2642,17 +2649,24 @@ read_integer (Lisp_Object readcharfun, EMACS_INT radix) | |||
| 2642 | { | 2649 | { |
| 2643 | /* Room for sign, leading 0, other digits, trailing null byte. | 2650 | /* Room for sign, leading 0, other digits, trailing null byte. |
| 2644 | Also, room for invalid syntax diagnostic. */ | 2651 | Also, room for invalid syntax diagnostic. */ |
| 2645 | char buf[max (1 + 1 + UINTMAX_WIDTH + 1, | 2652 | size_t len = max (1 + 1 + UINTMAX_WIDTH + 1, |
| 2646 | sizeof "integer, radix " + INT_STRLEN_BOUND (EMACS_INT))]; | 2653 | sizeof "integer, radix " + INT_STRLEN_BOUND (EMACS_INT)); |
| 2654 | char *buf = NULL; | ||
| 2647 | char *p = buf; | 2655 | char *p = buf; |
| 2648 | int valid = -1; /* 1 if valid, 0 if not, -1 if incomplete. */ | 2656 | int valid = -1; /* 1 if valid, 0 if not, -1 if incomplete. */ |
| 2649 | 2657 | ||
| 2658 | ptrdiff_t count = SPECPDL_INDEX (); | ||
| 2659 | |||
| 2650 | if (radix < 2 || radix > 36) | 2660 | if (radix < 2 || radix > 36) |
| 2651 | valid = 0; | 2661 | valid = 0; |
| 2652 | else | 2662 | else |
| 2653 | { | 2663 | { |
| 2654 | int c, digit; | 2664 | int c, digit; |
| 2655 | 2665 | ||
| 2666 | buf = xmalloc (len); | ||
| 2667 | record_unwind_protect_ptr (free_contents, &buf); | ||
| 2668 | p = buf; | ||
| 2669 | |||
| 2656 | c = READCHAR; | 2670 | c = READCHAR; |
| 2657 | if (c == '-' || c == '+') | 2671 | if (c == '-' || c == '+') |
| 2658 | { | 2672 | { |
| @@ -2678,8 +2692,15 @@ read_integer (Lisp_Object readcharfun, EMACS_INT radix) | |||
| 2678 | valid = 0; | 2692 | valid = 0; |
| 2679 | if (valid < 0) | 2693 | if (valid < 0) |
| 2680 | valid = 1; | 2694 | valid = 1; |
| 2681 | if (p < buf + sizeof buf) | 2695 | /* Allow 1 extra byte for the \0. */ |
| 2682 | *p++ = c; | 2696 | if (p + 1 == buf + len) |
| 2697 | { | ||
| 2698 | ptrdiff_t where = p - buf; | ||
| 2699 | len *= 2; | ||
| 2700 | buf = xrealloc (buf, len); | ||
| 2701 | p = buf + where; | ||
| 2702 | } | ||
| 2703 | *p++ = c; | ||
| 2683 | c = READCHAR; | 2704 | c = READCHAR; |
| 2684 | } | 2705 | } |
| 2685 | 2706 | ||
| @@ -2692,14 +2713,8 @@ read_integer (Lisp_Object readcharfun, EMACS_INT radix) | |||
| 2692 | invalid_syntax (buf); | 2713 | invalid_syntax (buf); |
| 2693 | } | 2714 | } |
| 2694 | 2715 | ||
| 2695 | if (p == buf + sizeof buf) | ||
| 2696 | { | ||
| 2697 | memset (p - 3, '.', 3); | ||
| 2698 | xsignal1 (Qoverflow_error, make_unibyte_string (buf, sizeof buf)); | ||
| 2699 | } | ||
| 2700 | |||
| 2701 | *p = '\0'; | 2716 | *p = '\0'; |
| 2702 | return string_to_number (buf, radix, 0); | 2717 | return unbind_to (count, string_to_number (buf, radix, 0)); |
| 2703 | } | 2718 | } |
| 2704 | 2719 | ||
| 2705 | 2720 | ||
| @@ -3508,9 +3523,7 @@ read1 (Lisp_Object readcharfun, int *pch, bool first_in_list) | |||
| 3508 | 3523 | ||
| 3509 | if (!quoted && !uninterned_symbol) | 3524 | if (!quoted && !uninterned_symbol) |
| 3510 | { | 3525 | { |
| 3511 | int flags = (read_integer_overflow_as_float | 3526 | Lisp_Object result = string_to_number (read_buffer, 10, 0); |
| 3512 | ? S2N_OVERFLOW_TO_FLOAT : 0); | ||
| 3513 | Lisp_Object result = string_to_number (read_buffer, 10, flags); | ||
| 3514 | if (! NILP (result)) | 3527 | if (! NILP (result)) |
| 3515 | return unbind_to (count, result); | 3528 | return unbind_to (count, result); |
| 3516 | } | 3529 | } |
| @@ -3677,12 +3690,10 @@ substitute_in_interval (INTERVAL interval, void *arg) | |||
| 3677 | 3690 | ||
| 3678 | /* Convert STRING to a number, assuming base BASE. When STRING has | 3691 | /* Convert STRING to a number, assuming base BASE. When STRING has |
| 3679 | floating point syntax and BASE is 10, return a nearest float. When | 3692 | floating point syntax and BASE is 10, return a nearest float. When |
| 3680 | STRING has integer syntax, return a fixnum if the integer fits, and | 3693 | STRING has integer syntax, return a fixnum if the integer fits, or |
| 3681 | signal an overflow otherwise (unless BASE is 10 and STRING ends in | 3694 | else a bignum. Otherwise, return nil. If FLAGS & |
| 3682 | period or FLAGS & S2N_OVERFLOW_TO_FLOAT is nonzero; in this case, | 3695 | S2N_IGNORE_TRAILING is nonzero, consider just the longest prefix of |
| 3683 | return a nearest float instead). Otherwise, return nil. If FLAGS | 3696 | STRING that has valid syntax. */ |
| 3684 | & S2N_IGNORE_TRAILING is nonzero, consider just the longest prefix | ||
| 3685 | of STRING that has valid syntax. */ | ||
| 3686 | 3697 | ||
| 3687 | Lisp_Object | 3698 | Lisp_Object |
| 3688 | string_to_number (char const *string, int base, int flags) | 3699 | string_to_number (char const *string, int base, int flags) |
| @@ -3796,13 +3807,7 @@ string_to_number (char const *string, int base, int flags) | |||
| 3796 | else | 3807 | else |
| 3797 | value = n; | 3808 | value = n; |
| 3798 | 3809 | ||
| 3799 | if (! (state & DOT_CHAR) && ! (flags & S2N_OVERFLOW_TO_FLOAT)) | 3810 | return make_bignum_str (string, base); |
| 3800 | { | ||
| 3801 | AUTO_STRING (fmt, ("%s is out of fixnum range; " | ||
| 3802 | "maybe set `read-integer-overflow-as-float'?")); | ||
| 3803 | AUTO_STRING_WITH_LEN (arg, string, cp - string); | ||
| 3804 | xsignal1 (Qoverflow_error, CALLN (Fformat_message, fmt, arg)); | ||
| 3805 | } | ||
| 3806 | } | 3811 | } |
| 3807 | 3812 | ||
| 3808 | /* Either the number uses float syntax, or it does not fit into a fixnum. | 3813 | /* Either the number uses float syntax, or it does not fit into a fixnum. |
| @@ -4845,13 +4850,6 @@ were read in. */); | |||
| 4845 | doc: /* Non-nil means read recursive structures using #N= and #N# syntax. */); | 4850 | doc: /* Non-nil means read recursive structures using #N= and #N# syntax. */); |
| 4846 | Vread_circle = Qt; | 4851 | Vread_circle = Qt; |
| 4847 | 4852 | ||
| 4848 | DEFVAR_BOOL ("read-integer-overflow-as-float", | ||
| 4849 | read_integer_overflow_as_float, | ||
| 4850 | doc: /* Non-nil means `read' quietly treats an out-of-range integer as floating point. | ||
| 4851 | Nil (the default) means signal an overflow unless the integer ends in `.'. | ||
| 4852 | This variable is experimental; email 30408@debbugs.gnu.org if you need it. */); | ||
| 4853 | read_integer_overflow_as_float = false; | ||
| 4854 | |||
| 4855 | DEFVAR_LISP ("load-path", Vload_path, | 4853 | DEFVAR_LISP ("load-path", Vload_path, |
| 4856 | doc: /* List of directories to search for files to load. | 4854 | doc: /* List of directories to search for files to load. |
| 4857 | Each element is a string (directory file name) or nil (meaning | 4855 | Each element is a string (directory file name) or nil (meaning |
diff --git a/src/process.c b/src/process.c index 10af79a0155..350cfe0f80b 100644 --- a/src/process.c +++ b/src/process.c | |||
| @@ -6842,7 +6842,7 @@ SIGCODE may be an integer, or a symbol whose name is a signal name. */) | |||
| 6842 | { | 6842 | { |
| 6843 | Lisp_Object tem = Fget_process (process); | 6843 | Lisp_Object tem = Fget_process (process); |
| 6844 | if (NILP (tem)) | 6844 | if (NILP (tem)) |
| 6845 | tem = string_to_number (SSDATA (process), 10, S2N_OVERFLOW_TO_FLOAT); | 6845 | tem = string_to_number (SSDATA (process), 10, 0); |
| 6846 | process = tem; | 6846 | process = tem; |
| 6847 | } | 6847 | } |
| 6848 | else if (!FIXED_OR_FLOATP (process)) | 6848 | else if (!FIXED_OR_FLOATP (process)) |