~ chicken-core (chicken-5) f5c5364723d70e1724bbfb4ece7312b2a88ef29b


commit f5c5364723d70e1724bbfb4ece7312b2a88ef29b
Author:     felix <felix@call-with-current-continuation.org>
AuthorDate: Mon Oct 18 04:14:45 2010 -0400
Commit:     felix <felix@call-with-current-continuation.org>
CommitDate: Mon Oct 18 04:14:45 2010 -0400

    support for blob-literals

diff --git a/c-backend.scm b/c-backend.scm
index f12bc7b6..4f1e5299 100644
--- a/c-backend.scm
+++ b/c-backend.scm
@@ -702,7 +702,7 @@
 	       (gen "C_h_intern(&" to #\, len #\, cstr ");") ) )
 	    ((null? lit) 
 	     (gen #t to "=C_SCHEME_END_OF_LIST;") )
-	    ((and (not (##sys#immediate? lit))
+	    ((and (not (##sys#immediate? lit)) ; nop
 		  (##core#inline "C_lambdainfop" lit)))
 	    ((or (fixnum? lit) (not (##sys#immediate? lit)))
 	     (gen #t to "=C_decode_literal(C_heaptop,")
diff --git a/chicken.h b/chicken.h
index b3260397..bcbeefbd 100644
--- a/chicken.h
+++ b/chicken.h
@@ -1557,6 +1557,7 @@ C_fctexport void C_fcall C_clear_trace_buffer(void) C_regparm;
 C_fctexport C_word C_fetch_trace(C_word start, C_word buffer);
 C_fctexport C_word C_fcall C_string(C_word **ptr, int len, C_char *str) C_regparm;
 C_fctexport C_word C_fcall C_static_string(C_word **ptr, int len, C_char *str) C_regparm;
+C_fctexport C_word C_fcall C_static_bytevector(C_word **ptr, int len, C_char *str) C_regparm;
 C_fctexport C_word C_fcall C_static_lambda_info(C_word **ptr, int len, C_char *str) C_regparm;
 C_fctexport C_word C_fcall C_bytevector(C_word **ptr, int len, C_char *str) C_regparm;
 C_fctexport C_word C_fcall C_pbytevector(int len, C_char *str) C_regparm;
diff --git a/library.scm b/library.scm
index 7fac6be1..ab03df94 100644
--- a/library.scm
+++ b/library.scm
@@ -2790,6 +2790,30 @@ EOF
 	      (fxior (fxshl (fxand hi #b111111) 10)
 		     (fxand lo #b1111111111)))) )
 
+(define (##sys#read-bytevector-literal port)
+  (define (hex c)
+    (let ((c (char-downcase c)))
+      (cond ((and (char>=? c #\a) (char<=? c #\f))
+	     (fx- (char->integer c) 87)	) ; - #\a + 10
+	    ((and (char>=? c #\0) (char<=? c #\9))
+	     (fx- (char->integer c) 48))
+	    (else (##sys#read-error port "invalid hex-code in blob-literal")))))
+  (let loop ((lst '()) (h #f))
+    (let ((c (##sys#read-char-0 port)))
+      (cond ((eof-object? c)
+	     (##sys#read-error port "unexpected end of blob literal"))
+	    ((char=? #\} c)
+	     (let ((str (##sys#reverse-list->string
+			 (if h
+			     (cons (integer->char h) lst)
+			     lst))))
+	       (##core#inline "C_string_to_bytevector" str)
+	       str))
+	    ((char-whitespace? c) (loop lst h))
+	    (h (loop (cons (integer->char (fxior h (hex c))) lst) #f))
+	    (else (loop lst (fxshl (hex c) 4)))))))
+	      
+
 ;;; Hooks for user-defined read-syntax:
 ;
 ; - Redefine this to handle new read-syntaxes. If 'char' doesn't match
@@ -2799,9 +2823,10 @@ EOF
 (define (##sys#user-read-hook char port)
   (case char
     ;; I put it here, so the SRFI-4 unit can intercept '#f...'
-    [(#\f #\F) (##sys#read-char-0 port) #f ]
-    [(#\t #\T) (##sys#read-char-0 port) #t ]
-    [else (##sys#read-error port "invalid sharp-sign read syntax" char) ] ) )
+    ((#\f #\F) (##sys#read-char-0 port) #f)
+    ((#\t #\T) (##sys#read-char-0 port) #t)
+    ((#\{) (##sys#read-char-0 port) (##sys#read-bytevector-literal port))
+    (else (##sys#read-error port "invalid sharp-sign read syntax" char) ) ) )
 
 
 ;;; Table for specially handled read-syntax:
diff --git a/runtime.c b/runtime.c
index c1ce3692..3ea009ba 100644
--- a/runtime.c
+++ b/runtime.c
@@ -2270,6 +2270,15 @@ C_regparm C_word C_fcall C_bytevector(C_word **ptr, int len, C_char *str)
 }
 
 
+C_regparm C_word C_fcall C_static_bytevector(C_word **ptr, int len, C_char *str)
+{
+  C_word strblock = C_static_string(ptr, len, str);
+
+  ((C_SCHEME_BLOCK *)strblock)->header = C_BYTEVECTOR_TYPE | len;
+  return strblock;
+}
+
+
 C_regparm C_word C_fcall C_pbytevector(int len, C_char *str)
 {
   C_SCHEME_BLOCK *pbv = C_malloc(len + sizeof(C_header));
@@ -8836,6 +8845,12 @@ static C_regparm C_word C_fcall decode_literal2(C_word **ptr, C_char **str,
     *str += size;
     break;
     
+  case C_BYTEVECTOR_TYPE:
+    /* ... as are bytevectors (blobs) */
+    val = C_static_bytevector(ptr, size, *str);
+    *str += size;
+    break;
+    
   case C_SYMBOL_TYPE:
     if(dest == NULL) 
       panic(C_text("invalid literal symbol destination"));
Trap