~ chicken-core (chicken-5) bf74435c21a89fc04265e0a528fade19c018ff86


commit bf74435c21a89fc04265e0a528fade19c018ff86
Author:     felix <felix@call-with-current-continuation.org>
AuthorDate: Tue Apr 12 12:58:25 2011 +0200
Commit:     felix <felix@call-with-current-continuation.org>
CommitDate: Tue Apr 12 12:58:25 2011 +0200

    printer/reader shadow I/O parameters to avoid error in error when a parameter is bound to an incorrect value or non-procedure; fixed inconsistencies with keywords and escapes in symbol names. perhaps.

diff --git a/library.scm b/library.scm
index 1872f3cc..bbd41cf5 100644
--- a/library.scm
+++ b/library.scm
@@ -2268,7 +2268,6 @@ EOF
 (define keyword-style (make-parameter #:suffix))
 (define parentheses-synonyms (make-parameter #t))
 (define symbol-escape (make-parameter #t))
-
 (define current-read-table (make-parameter (##sys#make-structure 'read-table #f #f #f)))
 
 (define ##sys#read-warning
@@ -2295,9 +2294,14 @@ EOF
        args) ) ) )
 
 (define ##sys#read
-  (let ([reverse reverse]
-	[string-append string-append]
-	[kwprefix (string (integer->char 0))])
+  (let ((reverse reverse)
+	(string-append string-append)
+	(keyword-style keyword-style)
+	(case-sensitive case-sensitive)
+	(parantheses-synonyms parantheses-synonyms)
+	(symbol-escape symbol-escape)
+	(current-read-table current-read-table)
+	(kwprefix (string (integer->char 0))))
     (lambda (port infohandler)
       (let ([csp (case-sensitive)]
 	    [ksp (keyword-style)]
@@ -2470,7 +2474,7 @@ EOF
 					 (let* ((tok (##sys#string-append "." (r-token)))
 						(n (and (char-numeric? c2) 
 							(##sys#string->number tok)))
-						(val (or n (resolve-symbol tok))) 
+						(val (or n (build-symbol tok))) 
 						(node (cons val '())) )
 					   (if first 
 					       (##sys#setslot last 1 node)
@@ -2507,7 +2511,7 @@ EOF
 			      "cannot represent exact fraction - coerced to flonum" tok) )
 			   val]
 			  [radix (##sys#read-error port "illegal number syntax" tok)]
-			  [else (resolve-symbol tok)] ) ) ) ) )
+			  [else (build-symbol tok)] ) ) ) ) )
 
 	  (define (r-number-with-exactness radix)
 	    (cond [(char=? #\# (##sys#peek-char-0 port))
@@ -2562,40 +2566,49 @@ EOF
 	    (r-token) )
 	  
 	  (define (r-symbol)
-	    (let ((s (resolve-symbol (r-xtoken))))
-	      (info 'symbol-info s (##sys#port-line port)) ) )
-
-	  (define (r-xtoken)
-	    (let loop ((lst '()))
-	      (let ((c (##sys#peek-char-0 port)))
-		(cond ((or (eof-object? c) 
-			   (char-whitespace? c)
-			   (memq c terminating-characters))
-		       (##sys#reverse-list->string lst))
-		      (else
-		       (let ((c (##sys#read-char-0 port)))
-			 (case (and sep c)
-			   ((#\|) 
-			    (let ((part (r-string #\|)))
-			      (string-append
-			       (##sys#reverse-list->string lst)
-			       part
-			       (loop '()))))
-			   ((#\newline)
-			    (##sys#read-warning
-			     port "escaped symbol syntax spans multiple lines"
-			     (##sys#reverse-list->string lst))
-			    (loop (cons #\newline lst)))
-			   ((#\\)
-			    (let ((c (##sys#read-char-0 port)))
-			      (if (eof-object? c)
-				  (##sys#read-error
-				   port
-				   "unexpected end of file while reading escaped character")
-				  (loop (cons c lst)))))
-			   (else 
-			    (loop 
-			     (cons (if csp c (char-downcase c)) lst))))))))))
+	    (r-xtoken
+	     (lambda (str kw)
+	       (let ((s (if kw (build-keyword str) (build-symbol str))))
+		 (info 'symbol-info s (##sys#port-line port)) ) )))
+
+	  (define (r-xtoken k)
+	    (let ((pkw #f))
+	      (let loop ((lst '()) (skw #f))
+		(let ((c (##sys#peek-char-0 port)))
+		  (cond ((or (eof-object? c) 
+			     (char-whitespace? c)
+			     (memq c terminating-characters))
+			 (if (and skw (eq? ksp #:suffix))
+			     (k (##sys#reverse-list->string (cdr lst)) #t)
+			     (k (##sys#reverse-list->string lst) pkw)))
+			(else
+			 (let ((c (##sys#read-char-0 port)))
+			   (case (and sep c)
+			     ((#\|) 
+			      (let ((part (r-string #\|)))
+				(loop (append (reverse (##sys#string->list part)) lst)
+				      #f)))
+			     ((#\newline)
+			      (##sys#read-warning
+			       port "escaped symbol syntax spans multiple lines"
+			       (##sys#reverse-list->string lst))
+			      (loop (cons #\newline lst) #f))
+			     ((#\:)
+			      (cond ((and (null? lst) (eq? ksp #:prefix))
+				     (set! pkw #t)
+				     (loop '() #f))
+				    (else (loop (cons #\: lst) #t))))
+			     ((#\\)
+			      (let ((c (##sys#read-char-0 port)))
+				(if (eof-object? c)
+				    (##sys#read-error
+				     port
+				     "unexpected end of file while reading escaped character")
+				    (loop (cons c lst) #f))))
+			     (else 
+			      (loop 
+			       (cons (if csp c (char-downcase c)) lst)
+			       #f))))))))))
 	  
 	  (define (r-char)
 	    ;; Code contributed by Alex Shinn
@@ -2611,7 +2624,8 @@ EOF
 				       (n0 (fxand (fxshr c0 4) 3))
 				       (n (fx+ 2 (fxand (fxior n0 (fxshr n0 1)) (fx- n0 1))))
 				       ((fx= len n))
-				       (res (fx+ (fxshl (fxand c0 (fx- (fxshl 1 (fx- 8 n)) 1)) 6)
+				       (res (fx+ (fxshl (fxand c0 (fx- (fxshl 1 (fx- 8 n)) 1))
+							6)
 						 (fxand (char->integer 
 							 (##core#inline "C_subchar" tk 1)) 
 							#b111111))))
@@ -2667,25 +2681,14 @@ EOF
 			 (##sys#substring tok (fx+ i 1) toklen)) ) ]
 		      [else (loop (fx+ i 1))] ) ) ) )
 
-	  (define (resolve-symbol tok)
-	    (let ([len (##sys#size tok)])
-	      (cond [(and (fx> len 1)
-			  (or (and (eq? ksp #:prefix)
-				   (char=? #\: (##core#inline "C_subchar" tok 0)) 
-				   (##sys#substring tok 1 len) )
-			      (and (eq? ksp #:suffix) 
-				   (char=? #\: (##core#inline "C_subchar" tok (fx- len 1)))
-				   (##sys#substring tok 0 (fx- len 1)) ) ) )
-		     => build-keyword]	; ugh
-		    [else (build-symbol tok)])))
-
 	  (define (build-symbol tok)
 	    (##sys#intern-symbol tok) )
 	  
 	  (define (build-keyword tok)
-	    (if (eq? 0 (##sys#size tok))
-		(##sys#read-error port "empty keyword")
-		(##sys#intern-symbol (##sys#string-append kwprefix tok)) ))
+	    (##sys#intern-symbol
+	     (if (eq? 0 (##sys#size tok))
+		 ":"
+		 (##sys#string-append kwprefix tok)) ))
 
           ; now have the state to make a decision.
           (set! reserved-characters
@@ -2787,7 +2790,10 @@ EOF
 					  (else (list 'location (readrec)) ))))
 				 ((#\:) 
 				  (##sys#read-char-0 port)
-				  (build-keyword (r-token)) )
+				  (let ((tok (r-token)))
+				    (if (eq? 0 (##sys#size tok))
+					(##sys#read-error port "empty keyword")
+					(build-keyword tok))))
 				 ((#\%)
 				  (build-symbol (##sys#string-append "#" (r-token))) )
 				 ((#\+)
@@ -3023,7 +3029,9 @@ EOF
 (define ##sys#print-exit (make-parameter #f))
 
 (define ##sys#print
-  (let ([string-append string-append])
+  (let ((string-append string-append)
+	(case-sensitive case-sensitive)
+	(keyword-style keyword-style))
     (lambda (x readable port)
       (##sys#check-port-mode port #f)
       (let ([csp (case-sensitive)]
@@ -3086,7 +3094,8 @@ EOF
 	    (cond ((eq? len 0) #f)
 		  ((eq? len 1)
 		   (let ((c (##core#inline "C_subchar" str 0)))
-		     (cond ((or (eq? #\. c) (eq? #\# c) (eq? #\; c) (eq? #\, c) (eq? #\| c)) #f)
+		     (cond ((or (eq? #\. c) (eq? #\# c) (eq? #\; c) (eq? #\, c) (eq? #\| c))
+			    #f)
 			   ((char-numeric? c) #f)
 			   (else #t))))
 		  (else
@@ -3098,15 +3107,18 @@ EOF
 				      (eq? c #\-)
 				      (eq? c #\.) )
 				  (not (##sys#string->number str)) )
+				 ((eq? c #\:) (not (eq? ksp #:prefix)))
 				 ((and (eq? c #\#)
-				       (or (not (eq? #\% (##core#inline "C_subchar" str 1)))
-					   (eq? #\: (##core#inline "C_subchar" str 1))))
+				       (not (eq? #\% (##core#inline "C_subchar" str 1))))
 				  #f)
 				 ((specialchar? c) #f)
 				 (else #t) ) )
 			 (let ((c (##core#inline "C_subchar" str i)))
 			   (and (or csp (not (char-upper-case? c)))
 				(not (specialchar? c))
+				(or (not (eq? c #\:))
+				    (fx< i (fx- len 1))
+				    (not (eq? ksp #:suffix)))
 				(loop (fx- i 1)) ) ) ) ) ) ) ) )
 
 	(let out ([x x])
diff --git a/tests/library-tests.scm b/tests/library-tests.scm
index 01974bac..a01f2b2f 100644
--- a/tests/library-tests.scm
+++ b/tests/library-tests.scm
@@ -113,10 +113,6 @@
 (assert (string=? "abcxyzdef" (symbol->string '|abc|xyz|def|)))
 (assert (string=? "abc|def" (symbol->string '|abc\|def|)))
 (assert (string=? "abc|def" (symbol->string '|abc\|def|)))
-(assert (string=? "abc" (symbol->string '|abc:|))) ; keyword
-(assert (string=? "abc" (symbol->string '|abc|:))) ; keyword
-(assert (string=? ":abc" (symbol->string ':|abc|)))
-(assert (string=? ":abc" (symbol->string '|:abc|)))
 (assert (string=? "abc" (symbol->string 'abc)))
 (assert (string=? "a c" (symbol->string 'a\ c)))
 (assert (string=? "aBc" (symbol->string 'aBc)))
@@ -127,6 +123,46 @@
   (assert (string=? "aBc" (symbol->string (with-input-from-string "a\\Bc" read)))))
 
 
+;;; keywords
+
+(parameterize ((keyword-style #:suffix))
+  (assert (string=? "abc:" (symbol->string (with-input-from-string "|abc:|" read))))
+  (assert (string=? "abc" (symbol->string (with-input-from-string "|abc|:" read))))) ; keyword
+
+(parameterize ((keyword-style #:prefix))
+  (assert (string=? "abc" (symbol->string (with-input-from-string ":|abc|" read))))
+  (assert (string=? ":abc" (symbol->string (with-input-from-string "|:abc|" read)))))
+
+(assert (eq? '|#:| (string->symbol "#:")))
+(assert-fail (with-input-from-string "#:" read)) ; empty keyword
+(assert (eq? '|#:| (with-input-from-string (with-output-to-string (cut write '|#:|)) read)))
+
+(parameterize ((keyword-style #:suffix))
+  (assert (keyword? (with-input-from-string "abc:" read)))
+  (assert (keyword? (with-input-from-string "|abc|:" read)))
+  (assert (not (keyword? (with-input-from-string "abc:||" read))))
+  (assert (not (keyword? (with-input-from-string "abc\\:" read))))
+  (assert (not (keyword? (with-input-from-string "abc|:|" read))))
+  (assert (not (keyword? (with-input-from-string "|abc:|" read)))))
+
+(parameterize ((keyword-style #:prefix))
+  (assert (keyword? (with-input-from-string ":abc" read)))
+  (assert (keyword? (with-input-from-string ":|abc|" read)))
+  (assert (keyword? (with-input-from-string "||:abc" read))) ;XXX should be not
+  (assert (not (keyword? (with-input-from-string "\\:abc" read))))
+  (assert (not (keyword? (with-input-from-string "|:|abc" read))))
+  (assert (not (keyword? (with-input-from-string "|:abc|" read)))))
+
+(parameterize ((keyword-style #f))
+  (assert (not (keyword? (with-input-from-string ":abc" read))))
+  (assert (not (keyword? (with-input-from-string ":abc:" read))))
+  (assert (not (keyword? (with-input-from-string "abc:" read)))))
+
+(assert (string=? ":" (symbol->string (with-input-from-string ":" read))))
+(assert (string=? ":" (symbol->string (with-input-from-string ":||" read))))
+(assert-fail (with-input-from-string "#:" read))
+
+
 ;;; setters
 
 (define x '(a b c))
Trap