changeset 5605:cc7f8a0e569a

Accept bignums unambiguously in the syntax for object labels, lread.c. src/ChangeLog addition: 2011-12-03 Aidan Kehoe <kehoea@parhasard.net> * lread.c (read1): Don't wrap when reading expressions that use bignums as object labels, that can lead to ambiguity and it's not actually that hard to use parse_integer() to avoid it. tests/ChangeLog addition: 2011-12-03 Aidan Kehoe <kehoea@parhasard.net> * automated/lisp-reader-tests.el: Check that integer object labels (using the #N=... syntax) treat bignums as such, rather than as fixnums that have wrapped.
author Aidan Kehoe <kehoea@parhasard.net>
date Sat, 03 Dec 2011 15:13:55 +0000
parents e9f58d024c3c
children 7c383c5784ed
files src/ChangeLog src/lread.c tests/ChangeLog tests/automated/lisp-reader-tests.el
diffstat 4 files changed, 38 insertions(+), 11 deletions(-) [+]
line wrap: on
line diff
--- a/src/ChangeLog	Tue Nov 29 16:19:53 2011 +0100
+++ b/src/ChangeLog	Sat Dec 03 15:13:55 2011 +0000
@@ -1,3 +1,10 @@
+2011-12-03  Aidan Kehoe  <kehoea@parhasard.net>
+
+	* lread.c (read1):
+	Don't wrap when reading expressions that use bignums as object
+	labels, that can lead to ambiguity and it's not actually that hard
+	to use parse_integer() to avoid it.
+
 2011-11-26  Aidan Kehoe  <kehoea@parhasard.net>
 
 	* number-mp.c (bignum_to_string):
--- a/src/lread.c	Tue Nov 29 16:19:53 2011 +0100
+++ b/src/lread.c	Sat Dec 03 15:13:55 2011 +0000
@@ -2697,20 +2697,29 @@
 	  case '5': case '6': case '7': case '8': case '9':
 	    /* Reader forms that can reuse previously read objects.  */
 	    {
-	      int n = 0;
-	      Lisp_Object found;
+	      Lisp_Object parsed, found;
+
+	      Lstream_rewind (XLSTREAM (Vread_buffer_stream));
 
 	      /* Using read_integer() here is impossible, because it
-                 chokes on `='.  Using parse_integer() is too hard.
-                 So we simply read it in, and ignore overflows, which
-                 is safe.  */
+                 chokes on `='. */
 	      while (c >= '0' && c <= '9')
 		{
-		  n *= 10;
-		  n += c - '0';
+		  Lstream_put_ichar (XLSTREAM (Vread_buffer_stream), c);
+		  QUIT;
 		  c = readchar (readcharfun);
 		}
-	      found = assq_no_quit (make_fixnum (n), Vread_objects);
+
+	      Lstream_flush (XLSTREAM (Vread_buffer_stream));
+
+	      parsed
+		= parse_integer (resizing_buffer_stream_ptr
+				 (XLSTREAM (Vread_buffer_stream)),
+				 Lstream_byte_count (XLSTREAM
+						     (Vread_buffer_stream)),
+				 10);
+
+	      found = assoc_no_quit (parsed, Vread_objects);
 	      if (c == '=')
 		{
 		  /* #n=object returns object, but associates it with
@@ -2720,13 +2729,13 @@
                       return Fsignal (Qinvalid_read_syntax,
                                       list2 (build_msg_string
                                              ("Multiply defined object label"),
-                                             make_fixnum (n)));
+                                             parsed));
                     }
                   else
                     {
                       Lisp_Object object;
 
-                      found = Fcons (make_fixnum (n), Qnil);
+                      found = Fcons (parsed, Qnil);
                       /* Make FOUND a placeholder for the object that will
                          be read. (We've just consed it, and it's not
                          visible from Lisp, so there's no possibility of
@@ -2751,7 +2760,7 @@
 		    return Fsignal (Qinvalid_read_syntax,
 				    list2 (build_msg_string
 					   ("Undefined symbol label"),
-					   make_fixnum (n)));
+					   parsed));
 		}
 	      return Fsignal (Qinvalid_read_syntax,
 			      list1 (build_ascstring ("#")));
--- a/tests/ChangeLog	Tue Nov 29 16:19:53 2011 +0100
+++ b/tests/ChangeLog	Sat Dec 03 15:13:55 2011 +0000
@@ -1,3 +1,9 @@
+2011-12-03  Aidan Kehoe  <kehoea@parhasard.net>
+
+	* automated/lisp-reader-tests.el:
+	Check that integer object labels (using the #N=... syntax) treat 
+	bignums as such, rather than as fixnums that have wrapped.
+
 2011-11-09  Aidan Kehoe  <kehoea@parhasard.net>
 
 	Update some tests that have started failing because of some
--- a/tests/automated/lisp-reader-tests.el	Tue Nov 29 16:19:53 2011 +0100
+++ b/tests/automated/lisp-reader-tests.el	Sat Dec 03 15:13:55 2011 +0000
@@ -150,3 +150,8 @@
               (car (get-range-table #x1001 deserialized-range-table)))
           "checking the lisp reader handles deserialization identity, mixed"))
 
+(when (featurep 'bignum)
+  (Assert (null (list-length (read (format "#%d=(1 #1=(5) 3 4 . #%d#)"
+					   (+ most-positive-fixnum 2)
+					   (+ most-positive-fixnum 2)))))
+	  "checking bignum object labels don't wrap on reading"))