emacs-diffs
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[Emacs-diffs] feature/bignum 1e8ae6c 06/24: Make the reader accept bignu


From: Tom Tromey
Subject: [Emacs-diffs] feature/bignum 1e8ae6c 06/24: Make the reader accept bignums
Date: Fri, 13 Jul 2018 00:25:07 -0400 (EDT)

branch: feature/bignum
commit 1e8ae6ca237e22e11b3db63a01e558ad5a3d6ef3
Author: Tom Tromey <address@hidden>
Commit: Tom Tromey <address@hidden>

    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.
---
 src/data.c    |  3 +--
 src/lisp.h    |  2 +-
 src/lread.c   | 66 +++++++++++++++++++++++++++++------------------------------
 src/process.c |  2 +-
 4 files changed, 35 insertions(+), 38 deletions(-)

diff --git a/src/data.c b/src/data.c
index efcffbb..8ffed8b 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.  */)
   while (*p == ' ' || *p == '\t')
     p++;
 
-  int flags = S2N_IGNORE_TRAILING | S2N_OVERFLOW_TO_FLOAT;
-  Lisp_Object val = string_to_number (p, b, flags);
+  Lisp_Object val = string_to_number (p, b, S2N_IGNORE_TRAILING);
   return NILP (val) ? make_fixnum (0) : val;
 }
 
diff --git a/src/lisp.h b/src/lisp.h
index 6a3db24..be67932 100644
--- a/src/lisp.h
+++ b/src/lisp.h
@@ -3858,7 +3858,7 @@ LOADHIST_ATTACH (Lisp_Object x)
 }
 extern int openp (Lisp_Object, Lisp_Object, Lisp_Object,
                   Lisp_Object *, Lisp_Object, bool);
-enum { S2N_IGNORE_TRAILING = 1, S2N_OVERFLOW_TO_FLOAT = 2 };
+enum { S2N_IGNORE_TRAILING = 1 };
 extern Lisp_Object string_to_number (char const *, int, int);
 extern void map_obarray (Lisp_Object, void (*) (Lisp_Object, Lisp_Object),
                          Lisp_Object);
diff --git a/src/lread.c b/src/lread.c
index 49fa51d..ff86c96 100644
--- a/src/lread.c
+++ b/src/lread.c
@@ -2631,6 +2631,13 @@ digit_to_number (int character, int base)
   return digit < base ? digit : -1;
 }
 
+static void
+free_contents (void *p)
+{
+  void **ptr = (void **) p;
+  xfree (*ptr);
+}
+
 /* Read an integer in radix RADIX using READCHARFUN to read
    characters.  RADIX must be in the interval [2..36]; if it isn't, a
    read error is signaled .  Value is the integer read.  Signals an
@@ -2642,17 +2649,24 @@ read_integer (Lisp_Object readcharfun, EMACS_INT radix)
 {
   /* Room for sign, leading 0, other digits, trailing null byte.
      Also, room for invalid syntax diagnostic.  */
-  char buf[max (1 + 1 + UINTMAX_WIDTH + 1,
-               sizeof "integer, radix " + INT_STRLEN_BOUND (EMACS_INT))];
+  size_t len = max (1 + 1 + UINTMAX_WIDTH + 1,
+                   sizeof "integer, radix " + INT_STRLEN_BOUND (EMACS_INT));
+  char *buf = NULL;
   char *p = buf;
   int valid = -1; /* 1 if valid, 0 if not, -1 if incomplete.  */
 
+  ptrdiff_t count = SPECPDL_INDEX ();
+
   if (radix < 2 || radix > 36)
     valid = 0;
   else
     {
       int c, digit;
 
+      buf = xmalloc (len);
+      record_unwind_protect_ptr (free_contents, &buf);
+      p = buf;
+
       c = READCHAR;
       if (c == '-' || c == '+')
        {
@@ -2678,8 +2692,15 @@ read_integer (Lisp_Object readcharfun, EMACS_INT radix)
            valid = 0;
          if (valid < 0)
            valid = 1;
-         if (p < buf + sizeof buf)
-           *p++ = c;
+         /* Allow 1 extra byte for the \0.  */
+         if (p + 1 == buf + len)
+           {
+             ptrdiff_t where = p - buf;
+             len *= 2;
+             buf = xrealloc (buf, len);
+             p = buf + where;
+           }
+         *p++ = c;
          c = READCHAR;
        }
 
@@ -2692,14 +2713,8 @@ read_integer (Lisp_Object readcharfun, EMACS_INT radix)
       invalid_syntax (buf);
     }
 
-  if (p == buf + sizeof buf)
-    {
-      memset (p - 3, '.', 3);
-      xsignal1 (Qoverflow_error, make_unibyte_string (buf, sizeof buf));
-    }
-
   *p = '\0';
-  return string_to_number (buf, radix, 0);
+  return unbind_to (count, string_to_number (buf, radix, 0));
 }
 
 
@@ -3508,9 +3523,7 @@ read1 (Lisp_Object readcharfun, int *pch, bool 
first_in_list)
 
        if (!quoted && !uninterned_symbol)
          {
-           int flags = (read_integer_overflow_as_float
-                        ? S2N_OVERFLOW_TO_FLOAT : 0);
-           Lisp_Object result = string_to_number (read_buffer, 10, flags);
+           Lisp_Object result = string_to_number (read_buffer, 10, 0);
            if (! NILP (result))
              return unbind_to (count, result);
          }
@@ -3677,12 +3690,10 @@ substitute_in_interval (INTERVAL interval, void *arg)
 
 /* Convert STRING to a number, assuming base BASE.  When STRING has
    floating point syntax and BASE is 10, return a nearest float.  When
-   STRING has integer syntax, return a fixnum if the integer fits, and
-   signal an overflow otherwise (unless BASE is 10 and STRING ends in
-   period or FLAGS & S2N_OVERFLOW_TO_FLOAT is nonzero; in this case,
-   return a nearest float instead).  Otherwise, return nil.  If FLAGS
-   & S2N_IGNORE_TRAILING is nonzero, consider just the longest prefix
-   of STRING that has valid syntax.  */
+   STRING has integer syntax, return a fixnum if the integer fits, or
+   else a bignum.  Otherwise, return nil.  If FLAGS &
+   S2N_IGNORE_TRAILING is nonzero, consider just the longest prefix of
+   STRING that has valid syntax.  */
 
 Lisp_Object
 string_to_number (char const *string, int base, int flags)
@@ -3796,13 +3807,7 @@ string_to_number (char const *string, int base, int 
flags)
       else
        value = n;
 
-      if (! (state & DOT_CHAR) && ! (flags & S2N_OVERFLOW_TO_FLOAT))
-       {
-         AUTO_STRING (fmt, ("%s is out of fixnum range; "
-                            "maybe set `read-integer-overflow-as-float'?"));
-         AUTO_STRING_WITH_LEN (arg, string, cp - string);
-         xsignal1 (Qoverflow_error, CALLN (Fformat_message, fmt, arg));
-       }
+      return make_bignum_str (string, base);
     }
 
   /* Either the number uses float syntax, or it does not fit into a fixnum.
@@ -4845,13 +4850,6 @@ were read in.  */);
               doc: /* Non-nil means read recursive structures using #N= and 
#N# syntax.  */);
   Vread_circle = Qt;
 
-  DEFVAR_BOOL ("read-integer-overflow-as-float",
-              read_integer_overflow_as_float,
-              doc: /* Non-nil means `read' quietly treats an out-of-range 
integer as floating point.
-Nil (the default) means signal an overflow unless the integer ends in `.'.
-This variable is experimental; email address@hidden if you need it.  */);
-  read_integer_overflow_as_float = false;
-
   DEFVAR_LISP ("load-path", Vload_path,
               doc: /* List of directories to search for files to load.
 Each element is a string (directory file name) or nil (meaning
diff --git a/src/process.c b/src/process.c
index 10af79a..350cfe0 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.  */)
     {
       Lisp_Object tem = Fget_process (process);
       if (NILP (tem))
-       tem = string_to_number (SSDATA (process), 10, S2N_OVERFLOW_TO_FLOAT);
+       tem = string_to_number (SSDATA (process), 10, 0);
       process = tem;
     }
   else if (!FIXED_OR_FLOATP (process))



reply via email to

[Prev in Thread] Current Thread [Next in Thread]