~ chicken-core (chicken-5) 05f341e07a179ea95d891e5c55b2fe3d0dbe1ffe


commit 05f341e07a179ea95d891e5c55b2fe3d0dbe1ffe
Author:     Evan Hanson <evhan@foldling.org>
AuthorDate: Wed Mar 14 17:53:00 2018 +1300
Commit:     Evan Hanson <evhan@foldling.org>
CommitDate: Mon Mar 19 08:24:45 2018 +1300

    Print #!-style symbols verbatim, without pipes
    
    These symbols are readable, so should be printed as-is by `##sys#print'
    just like #:keywords or the #!eof token.
    
    This has the side effect of making some lambda-infos look nicer in
    interpreted code, since the DSSSL indicators ("#!optional" et al.) will
    print verbatim rather than being enclosed by pipes, e.g. "(foo #!key x)"
    rather than "(foo |#!key| x)".
    
    Symbols that start with #% are no longer readable unquoted.
    
    Signed-off-by: Peter Bex <peter@more-magic.net>

diff --git a/NEWS b/NEWS
index 3ea766cf..d742c1d2 100644
--- a/NEWS
+++ b/NEWS
@@ -23,6 +23,9 @@
     software-version is now "cygwin" or "mingw32" instead of "unknown".
     This also means the features list will now contain the tool chain
     on all platforms.
+  - Symbols starting with #% are no longer treated specially and need
+    to be quoted with pipes. This makes the "%" sign available for use
+    in custom/user-defined sharp-sign read syntax.
 
 - Compiler
   - Fixed an off by one allocation problem in generated C code for (list ...).
diff --git a/library.scm b/library.scm
index 27d9ffe8..89cd285e 100644
--- a/library.scm
+++ b/library.scm
@@ -4294,8 +4294,6 @@ EOF
 						     (not (char=? c #\|)))
 						(##sys#read-error port "empty keyword")
 						(build-keyword str)))))))
-				    ((#\%)
-				     (build-symbol (##sys#string-append "#" (r-token))) )
 				    ((#\+)
 				     (##sys#read-char-0 port)
 				     (let ((tst (readrec)))
@@ -4560,9 +4558,8 @@ EOF
 				      (eq? c #\-) )
 				  (not (##sys#string->number str)) )
 				 ((eq? c #\:) (not (eq? ksp #:prefix)))
-				 ((and (eq? c #\#)
-				       (not (eq? #\% (##core#inline "C_subchar" str 1))))
-				  #f)
+				 ((eq? c #\#) ;; #!rest, #!key etc
+				  (eq? (##core#inline "C_subchar" str 1) #\!))
 				 ((specialchar? c) #f)
 				 (else #t) ) )
 			 (let ((c (##core#inline "C_subchar" str i)))
diff --git a/tests/syntax-tests.scm b/tests/syntax-tests.scm
index b119ee84..6bdfec45 100644
--- a/tests/syntax-tests.scm
+++ b/tests/syntax-tests.scm
@@ -1,7 +1,7 @@
 ;;;; syntax-tests.scm - various macro tests
 
 (import-for-syntax chicken.pretty-print)
-(import chicken.gc chicken.pretty-print)
+(import chicken.gc chicken.pretty-print chicken.port)
 
 (define-syntax t
   (syntax-rules ()
@@ -264,10 +264,23 @@
 ;; and not documented, but shouldn't be messed with by the expander
 
 (t "foo#bar" (symbol->string 'foo#bar))
-(t "#%void" (symbol->string '#%void))
-
 (t "foo#bar" (symbol->string (strip-syntax 'foo#bar)))
-(t "#%void" (symbol->string (strip-syntax '#%void)))
+
+(t "#!rest" (symbol->string '#!rest))
+(t "#!rest" (symbol->string '|#!rest|))
+(t "#!rest" (symbol->string (strip-syntax '#!rest)))
+
+;; Read-write invariance of "special" symbols
+
+(t '#!rest (with-input-from-string "#!rest" read))
+(t '#!rest (with-input-from-string "|#!rest|" read))
+(t "#!rest" (with-output-to-string (lambda () (write '#!rest))))
+(t "foo#bar" (with-output-to-string (lambda () (write 'foo#bar))))
+
+;; These used to be treated specially, but now they just trigger an
+;; "invalid sharp-sign read syntax" error.
+(t "|#%foo|" (with-output-to-string (lambda () (write '|#%foo|))))
+(f (with-input-from-string "#%foo" read))
 
 ;;; alternative ellipsis test (SRFI-46)
 
Trap