emacs-diffs
[Top][All Lists]
Advanced

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

master de45864 2/2: Fix lexing of numbers with trailing decimal point an


From: Mattias Engdegård
Subject: master de45864 2/2: Fix lexing of numbers with trailing decimal point and exponent
Date: Thu, 27 May 2021 08:20:14 -0400 (EDT)

branch: master
commit de45864cf787ce244b0d97e7cf523a6e03743f10
Author: Mattias Engdegård <mattiase@acm.org>
Commit: Mattias Engdegård <mattiase@acm.org>

    Fix lexing of numbers with trailing decimal point and exponent
    
    Numbers with a trailing dot and an exponent were incorrectly read as
    integers (with the exponent ignored) instead of the floats they should
    be.  For example, 1.e6 was read as the integer 1, not 1000000.0 as
    every sane person would agree was meant. (Bug#48678)
    
    Numbers with a trailing dot but no exponent are still read as
    integers.
    
    * src/lread.c (string_to_number): Fix float lexing.
    * test/src/lread-tests.el (lread-float): Add test.
    * doc/lispref/numbers.texi (Float Basics): Clarify syntax.
---
 doc/lispref/numbers.texi |  3 ++-
 src/lread.c              | 10 ++++----
 test/src/lread-tests.el  | 67 ++++++++++++++++++++++++++++++++++++++++++++++++
 3 files changed, 74 insertions(+), 6 deletions(-)

diff --git a/doc/lispref/numbers.texi b/doc/lispref/numbers.texi
index 4c5f7212..d28e158 100644
--- a/doc/lispref/numbers.texi
+++ b/doc/lispref/numbers.texi
@@ -237,7 +237,8 @@ precede the number and its exponent.  For example, 
@samp{1500.0},
 @samp{+15e2}, @samp{15.0e+2}, @samp{+1500000e-3}, and @samp{.15e4} are
 five ways of writing a floating-point number whose value is 1500.
 They are all equivalent.  Like Common Lisp, Emacs Lisp requires at
-least one digit after any decimal point in a floating-point number;
+least one digit after a decimal point in a floating-point number that
+does not have an exponent;
 @samp{1500.} is an integer, not a floating-point number.
 
   Emacs Lisp treats @code{-0.0} as numerically equal to ordinary zero
diff --git a/src/lread.c b/src/lread.c
index bca53a9..0b33fd0 100644
--- a/src/lread.c
+++ b/src/lread.c
@@ -3938,8 +3938,7 @@ string_to_number (char const *string, int base, ptrdiff_t 
*plen)
   bool signedp = negative | positive;
   cp += signedp;
 
-  enum { INTOVERFLOW = 1, LEAD_INT = 2, DOT_CHAR = 4, TRAIL_INT = 8,
-        E_EXP = 16 };
+  enum { INTOVERFLOW = 1, LEAD_INT = 2, TRAIL_INT = 4, E_EXP = 16 };
   int state = 0;
   int leading_digit = digit_to_number (*cp, base);
   uintmax_t n = leading_digit;
@@ -3959,7 +3958,6 @@ string_to_number (char const *string, int base, ptrdiff_t 
*plen)
   char const *after_digits = cp;
   if (*cp == '.')
     {
-      state |= DOT_CHAR;
       cp++;
     }
 
@@ -4008,8 +4006,10 @@ string_to_number (char const *string, int base, 
ptrdiff_t *plen)
            cp = ecp;
        }
 
-      float_syntax = ((state & (DOT_CHAR|TRAIL_INT)) == (DOT_CHAR|TRAIL_INT)
-                     || (state & ~INTOVERFLOW) == (LEAD_INT|E_EXP));
+      /* A float has digits after the dot or an exponent.
+        This excludes numbers like "1." which are lexed as integers. */
+      float_syntax = ((state & TRAIL_INT)
+                     || ((state & LEAD_INT) && (state & E_EXP)));
     }
 
   if (plen)
diff --git a/test/src/lread-tests.el b/test/src/lread-tests.el
index f2a60bc..dac8f95 100644
--- a/test/src/lread-tests.el
+++ b/test/src/lread-tests.el
@@ -196,4 +196,71 @@ literals (Bug#20852)."
     (should-error (read-event "foo: "))
     (should-error (read-char-exclusive "foo: "))))
 
+(ert-deftest lread-float ()
+  (should (equal (read "13") 13))
+  (should (equal (read "+13") 13))
+  (should (equal (read "-13") -13))
+  (should (equal (read "13.") 13))
+  (should (equal (read "+13.") 13))
+  (should (equal (read "-13.") -13))
+  (should (equal (read "13.25") 13.25))
+  (should (equal (read "+13.25") 13.25))
+  (should (equal (read "-13.25") -13.25))
+  (should (equal (read ".25") 0.25))
+  (should (equal (read "+.25") 0.25))
+  (should (equal (read "-.25") -0.25))
+  (should (equal (read "13e4") 130000.0))
+  (should (equal (read "+13e4") 130000.0))
+  (should (equal (read "-13e4") -130000.0))
+  (should (equal (read "13e+4") 130000.0))
+  (should (equal (read "+13e+4") 130000.0))
+  (should (equal (read "-13e+4") -130000.0))
+  (should (equal (read "625e-4") 0.0625))
+  (should (equal (read "+625e-4") 0.0625))
+  (should (equal (read "-625e-4") -0.0625))
+  (should (equal (read "1.25e2") 125.0))
+  (should (equal (read "+1.25e2") 125.0))
+  (should (equal (read "-1.25e2") -125.0))
+  (should (equal (read "1.25e+2") 125.0))
+  (should (equal (read "+1.25e+2") 125.0))
+  (should (equal (read "-1.25e+2") -125.0))
+  (should (equal (read "1.25e-1") 0.125))
+  (should (equal (read "+1.25e-1") 0.125))
+  (should (equal (read "-1.25e-1") -0.125))
+  (should (equal (read "4.e3") 4000.0))
+  (should (equal (read "+4.e3") 4000.0))
+  (should (equal (read "-4.e3") -4000.0))
+  (should (equal (read "4.e+3") 4000.0))
+  (should (equal (read "+4.e+3") 4000.0))
+  (should (equal (read "-4.e+3") -4000.0))
+  (should (equal (read "5.e-1") 0.5))
+  (should (equal (read "+5.e-1") 0.5))
+  (should (equal (read "-5.e-1") -0.5))
+  (should (equal (read "0") 0))
+  (should (equal (read "+0") 0))
+  (should (equal (read "-0") 0))
+  (should (equal (read "0.") 0))
+  (should (equal (read "+0.") 0))
+  (should (equal (read "-0.") 0))
+  (should (equal (read "0.0") 0.0))
+  (should (equal (read "+0.0") 0.0))
+  (should (equal (read "-0.0") -0.0))
+  (should (equal (read "0e5") 0.0))
+  (should (equal (read "+0e5") 0.0))
+  (should (equal (read "-0e5") -0.0))
+  (should (equal (read "0e-5") 0.0))
+  (should (equal (read "+0e-5") 0.0))
+  (should (equal (read "-0e-5") -0.0))
+  (should (equal (read ".0e-5") 0.0))
+  (should (equal (read "+.0e-5") 0.0))
+  (should (equal (read "-.0e-5") -0.0))
+  (should (equal (read "0.0e-5") 0.0))
+  (should (equal (read "+0.0e-5") 0.0))
+  (should (equal (read "-0.0e-5") -0.0))
+  (should (equal (read "0.e-5") 0.0))
+  (should (equal (read "+0.e-5") 0.0))
+  (should (equal (read "-0.e-5") -0.0))
+  )
+
+
 ;;; lread-tests.el ends here



reply via email to

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