~ chicken-core (chicken-5) 96e023e70a5c5769493b9da72b02bf8ef8130cdb


commit 96e023e70a5c5769493b9da72b02bf8ef8130cdb
Author:     felix <felix@call-with-current-continuation.org>
AuthorDate: Mon Oct 6 12:12:44 2025 +0200
Commit:     felix <felix@call-with-current-continuation.org>
CommitDate: Mon Oct 6 12:12:44 2025 +0200

    fixed several bugs in complex number vectors, add tests
    
    (thanks to jcroisant for reporting this)

diff --git a/srfi-4.scm b/srfi-4.scm
index 600fd401..5ee8e096 100644
--- a/srfi-4.scm
+++ b/srfi-4.scm
@@ -275,11 +275,16 @@ EOF
   (getter-with-setter
    (lambda (x i)
      (##sys#check-structure x 'c64vector 'c64vector-ref)
-     (##sys#check-range i 0 (fx/ (##core#inline "C_i_bytevector_length" (##sys#slot x 1))
-                                 8) 'c64vector-ref)
-     (let ((p (fx/ i 2)))
-       (make-rectangular (##core#inline_allocate ("C_a_u_i_f32vector_ref" 4) x p)
-                         (##core#inline_allocate ("C_a_u_i_f32vector_ref" 4) x (fx+ p 1)))))
+     (##sys#check-range
+       i 0 (##core#inline "C_u_fixnum_divide"
+             (##core#inline "C_i_bytevector_length" (##sys#slot x 1))
+             8)
+       'c64vector-ref)
+     (let ((p (##core#inline "C_fixnum_times" i 2)))
+       (make-rectangular
+         (##core#inline_allocate ("C_a_u_i_f32vector_ref" 4) x p)
+         (##core#inline_allocate ("C_a_u_i_f32vector_ref" 4)
+           x (##core#inline "C_u_fixnum_plus" p 1)))))
    c64vector-set!
    "(chicken.number-vector#c64vector-ref v i)"))
 
@@ -287,11 +292,16 @@ EOF
   (getter-with-setter
    (lambda (x i)
      (##sys#check-structure x 'c128vector 'c128vector-ref)
-     (##sys#check-range i 0 (fx/ (##core#inline "C_i_bytevector_length" (##sys#slot x 1))
-                                 16) 'c128vector-ref)
-     (let ((p (fx/ i 2)))
-       (make-rectangular (##core#inline_allocate ("C_a_u_i_f64vector_ref" 4) x p)
-                         (##core#inline_allocate ("C_a_u_i_f64vector_ref" 4) x (fx+ p 1)))))
+     (##sys#check-range
+       i 0 (##core#inline "C_u_fixnum_divide"
+             (##core#inline "C_i_bytevector_length" (##sys#slot x 1))
+             16)
+       'c128vector-ref)
+     (let ((p (##core#inline "C_fixnum_times" i 2)))
+       (make-rectangular
+          (##core#inline_allocate ("C_a_u_i_f64vector_ref" 4) x p)
+          (##core#inline_allocate ("C_a_u_i_f64vector_ref" 4)
+            x (##core#inline "C_u_fixnum_plus" p 1)))))
    c128vector-set!
    "(chicken.number-vector#c128vector-ref v i)"))
 
@@ -313,206 +323,212 @@ EOF
 (define release-number-vector)
 
 (let* ((ext-alloc
-	(foreign-lambda* scheme-object ((size_t bytes))
-	  "if (bytes > C_HEADER_SIZE_MASK) C_return(C_SCHEME_FALSE);"
-	  "C_word *buf = (C_word *)C_malloc(bytes + sizeof(C_header));"
-	  "if(buf == NULL) C_return(C_SCHEME_FALSE);"
-	  "C_block_header_init(buf, C_make_header(C_BYTEVECTOR_TYPE, bytes));"
-	  "C_return(buf);") )
+        (foreign-lambda* scheme-object ((size_t bytes))
+          "if (bytes > C_HEADER_SIZE_MASK) C_return(C_SCHEME_FALSE);"
+          "C_word *buf = (C_word *)C_malloc(bytes + sizeof(C_header));"
+          "if(buf == NULL) C_return(C_SCHEME_FALSE);"
+          "C_block_header_init(buf, C_make_header(C_BYTEVECTOR_TYPE, bytes));"
+          "C_return(buf);") )
        (ext-free
-	(foreign-lambda* void ((scheme-object bv))
-	  "C_free((void *)C_block_item(bv, 1));") )
+        (foreign-lambda* void ((scheme-object bv))
+          "C_free((void *)C_block_item(bv, 1));") )
+       (real-part real-part)
+       (imag-part imag-part)
        (alloc
-	(lambda (loc elem-size elems ext?)
-	  (##sys#check-fixnum elems loc)
-	  (when (fx< elems 0) (##sys#error loc "size is negative" elems))
-	  (let ((len (fx*? elems elem-size)))
-	    (unless len (##sys#error "overflow - cannot allocate the required number of elements" elems))
-	    (if ext?
-		(let ((bv (ext-alloc len)))
-		  (or bv
-		      (##sys#error loc "not enough memory - cannot allocate external number vector" len)) )
-		(##sys#allocate-bytevector len #f))))))
+        (lambda (loc elem-size elems ext?)
+          (##sys#check-fixnum elems loc)
+          (when (fx< elems 0) (##sys#error loc "size is negative" elems))
+          (let ((len (fx*? elems elem-size)))
+            (unless len (##sys#error "overflow - cannot allocate the required number of elements" elems))
+            (if ext?
+                (let ((bv (ext-alloc len)))
+                  (or bv
+                      (##sys#error loc "not enough memory - cannot allocate external number vector" len)) )
+                (##sys#allocate-bytevector len #f))))))
 
   (set! release-number-vector
     (lambda (v)
       (if (number-vector? v)
-	  (ext-free v)
-	  (##sys#error 'release-number-vector "bad argument type - not a number vector" v)) ) )
+          (ext-free v)
+          (##sys#error 'release-number-vector "bad argument type - not a number vector" v)) ) )
 
   (set! make-u8vector
     (lambda (len #!optional (init #f)  (ext? #f) (fin? #t))
       (let ((v (alloc 'make-u8vector 1 len ext?)))
-	(when (and ext? fin?) (set-finalizer! v ext-free))
-	(if (not init)
-	    v
-	    (begin
-	      (check-uint-length init 8 'make-u8vector)
-	      (do ((i 0 (##core#inline "C_fixnum_plus" i 1)))
-		  ((##core#inline "C_fixnum_greater_or_equal_p" i len) v)
-		(##core#inline "C_setsubbyte" v i init) ) ) ) ) ) )
+        (when (and ext? fin?) (set-finalizer! v ext-free))
+        (if (not init)
+            v
+            (begin
+              (check-uint-length init 8 'make-u8vector)
+              (do ((i 0 (##core#inline "C_fixnum_plus" i 1)))
+                  ((##core#inline "C_fixnum_greater_or_equal_p" i len) v)
+                (##core#inline "C_setsubbyte" v i init) ) ) ) ) ) )
 
   (set! make-s8vector
     (lambda (len #!optional (init #f)  (ext? #f) (fin? #t))
       (let ((v (##sys#make-structure 's8vector (alloc 'make-s8vector 1 len ext?))))
-	(when (and ext? fin?) (set-finalizer! v ext-free))
-	(if (not init)
-	    v
-	    (begin
-	      (check-uint-length init 8 'make-s8vector)
-	      (do ((i 0 (##core#inline "C_fixnum_plus" i 1)))
-		  ((##core#inline "C_fixnum_greater_or_equal_p" i len) v)
-		(##core#inline "C_u_i_s8vector_set" v i init) ) ) ) ) ) )
+        (when (and ext? fin?) (set-finalizer! v ext-free))
+        (if (not init)
+            v
+            (begin
+              (check-uint-length init 8 'make-s8vector)
+              (do ((i 0 (##core#inline "C_fixnum_plus" i 1)))
+                  ((##core#inline "C_fixnum_greater_or_equal_p" i len) v)
+                (##core#inline "C_u_i_s8vector_set" v i init) ) ) ) ) ) )
 
   (set! make-u16vector
     (lambda (len #!optional (init #f)  (ext? #f) (fin? #t))
       (let ((v (##sys#make-structure 'u16vector (alloc 'make-u16vector 2 len ext?))))
-	(when (and ext? fin?) (set-finalizer! v ext-free))
-	(if (not init)
-	    v
-	    (begin
-	      (check-uint-length init 16 'make-u16vector)
-	      (do ((i 0 (##core#inline "C_fixnum_plus" i 1)))
-		  ((##core#inline "C_fixnum_greater_or_equal_p" i len) v)
-		(##core#inline "C_u_i_u16vector_set" v i init) ) ) ) ) ) )
+        (when (and ext? fin?) (set-finalizer! v ext-free))
+        (if (not init)
+            v
+            (begin
+              (check-uint-length init 16 'make-u16vector)
+              (do ((i 0 (##core#inline "C_fixnum_plus" i 1)))
+                  ((##core#inline "C_fixnum_greater_or_equal_p" i len) v)
+                (##core#inline "C_u_i_u16vector_set" v i init) ) ) ) ) ) )
 
   (set! make-s16vector
     (lambda (len #!optional (init #f)  (ext? #f) (fin? #t))
       (let ((v (##sys#make-structure 's16vector (alloc 'make-s16vector 2 len ext?))))
-	(when (and ext? fin?) (set-finalizer! v ext-free))
-	(if (not init)
-	    v
-	    (begin
-	      (check-int-length init 16 'make-s16vector)
-	      (do ((i 0 (##core#inline "C_fixnum_plus" i 1)))
-		  ((##core#inline "C_fixnum_greater_or_equal_p" i len) v)
-		(##core#inline "C_u_i_s16vector_set" v i init) ) ) ) ) ) )
+        (when (and ext? fin?) (set-finalizer! v ext-free))
+        (if (not init)
+            v
+            (begin
+              (check-int-length init 16 'make-s16vector)
+              (do ((i 0 (##core#inline "C_fixnum_plus" i 1)))
+                  ((##core#inline "C_fixnum_greater_or_equal_p" i len) v)
+                (##core#inline "C_u_i_s16vector_set" v i init) ) ) ) ) ) )
 
   (set! make-u32vector
     (lambda (len #!optional (init #f)  (ext? #f) (fin? #t))
       (let ((v (##sys#make-structure 'u32vector (alloc 'make-u32vector 4 len ext?))))
-	(when (and ext? fin?) (set-finalizer! v ext-free))
-	(if (not init)
-	    v
-	    (begin
-	      (check-uint-length init 32 'make-u32vector)
-	      (do ((i 0 (##core#inline "C_fixnum_plus" i 1)))
-		  ((##core#inline "C_fixnum_greater_or_equal_p" i len) v)
-		(##core#inline "C_u_i_u32vector_set" v i init) ) ) ) ) ) )
+        (when (and ext? fin?) (set-finalizer! v ext-free))
+        (if (not init)
+            v
+            (begin
+              (check-uint-length init 32 'make-u32vector)
+              (do ((i 0 (##core#inline "C_fixnum_plus" i 1)))
+                  ((##core#inline "C_fixnum_greater_or_equal_p" i len) v)
+                (##core#inline "C_u_i_u32vector_set" v i init) ) ) ) ) ) )
 
   (set! make-u64vector
     (lambda (len #!optional (init #f)  (ext? #f) (fin? #t))
       (let ((v (##sys#make-structure 'u64vector (alloc 'make-u64vector 8 len ext?))))
-	(when (and ext? fin?) (set-finalizer! v ext-free))
-	(if (not init)
-	    v
-	    (begin
-	      (check-uint-length init 64 'make-u64vector)
-	      (do ((i 0 (##core#inline "C_fixnum_plus" i 1)))
-		  ((##core#inline "C_fixnum_greater_or_equal_p" i len) v)
-		(##core#inline "C_u_i_u64vector_set" v i init) ) ) ) ) ) )
+        (when (and ext? fin?) (set-finalizer! v ext-free))
+        (if (not init)
+            v
+            (begin
+              (check-uint-length init 64 'make-u64vector)
+              (do ((i 0 (##core#inline "C_fixnum_plus" i 1)))
+                  ((##core#inline "C_fixnum_greater_or_equal_p" i len) v)
+                (##core#inline "C_u_i_u64vector_set" v i init) ) ) ) ) ) )
 
   (set! make-s32vector
     (lambda (len #!optional (init #f)  (ext? #f) (fin? #t))
       (let ((v (##sys#make-structure 's32vector (alloc 'make-s32vector 4 len ext?))))
-	(when (and ext? fin?) (set-finalizer! v ext-free))
-	(if (not init)
-	    v
-	    (begin
-	      (check-int-length init 32 'make-s32vector)
-	      (do ((i 0 (##core#inline "C_fixnum_plus" i 1)))
-		  ((##core#inline "C_fixnum_greater_or_equal_p" i len) v)
-		(##core#inline "C_u_i_s32vector_set" v i init) ) ) ) ) ) )
+        (when (and ext? fin?) (set-finalizer! v ext-free))
+        (if (not init)
+            v
+            (begin
+              (check-int-length init 32 'make-s32vector)
+              (do ((i 0 (##core#inline "C_fixnum_plus" i 1)))
+                  ((##core#inline "C_fixnum_greater_or_equal_p" i len) v)
+                (##core#inline "C_u_i_s32vector_set" v i init) ) ) ) ) ) )
 
    (set! make-s64vector
     (lambda (len #!optional (init #f)  (ext? #f) (fin? #t))
       (let ((v (##sys#make-structure 's64vector (alloc 'make-s64vector 8 len ext?))))
-	(when (and ext? fin?) (set-finalizer! v ext-free))
-	(if (not init)
-	    v
-	    (begin
-	      (check-int-length init 64 'make-s64vector)
-	      (do ((i 0 (##core#inline "C_fixnum_plus" i 1)))
-		  ((##core#inline "C_fixnum_greater_or_equal_p" i len) v)
-		(##core#inline "C_u_i_s64vector_set" v i init) ) ) ) ) ) )
+        (when (and ext? fin?) (set-finalizer! v ext-free))
+        (if (not init)
+            v
+            (begin
+              (check-int-length init 64 'make-s64vector)
+              (do ((i 0 (##core#inline "C_fixnum_plus" i 1)))
+                  ((##core#inline "C_fixnum_greater_or_equal_p" i len) v)
+                (##core#inline "C_u_i_s64vector_set" v i init) ) ) ) ) ) )
 
   (set! make-f32vector
     (lambda (len #!optional (init #f)  (ext? #f) (fin? #t))
       (let ((v (##sys#make-structure 'f32vector (alloc 'make-f32vector 4 len ext?))))
-	(when (and ext? fin?) (set-finalizer! v ext-free))
-	(if (not init)
-	    v
-	    (begin
-	      (check-int/flonum init 'make-f32vector)
-	      (unless (##core#inline "C_i_flonump" init)
-		(set! init (##core#inline_allocate ("C_a_u_i_int_to_flo" 4) init)))
-	      (do ((i 0 (##core#inline "C_fixnum_plus" i 1)))
-		  ((##core#inline "C_fixnum_greater_or_equal_p" i len) v)
-		(##core#inline "C_u_i_f32vector_set" v i init) ) ) ) ) ) )
+        (when (and ext? fin?) (set-finalizer! v ext-free))
+        (if (not init)
+            v
+            (begin
+              (check-int/flonum init 'make-f32vector)
+              (unless (##core#inline "C_i_flonump" init)
+                (set! init (##core#inline_allocate ("C_a_u_i_int_to_flo" 4) init)))
+              (do ((i 0 (##core#inline "C_fixnum_plus" i 1)))
+                  ((##core#inline "C_fixnum_greater_or_equal_p" i len) v)
+                (##core#inline "C_u_i_f32vector_set" v i init) ) ) ) ) ) )
 
   (set! make-f64vector
     (lambda (len #!optional (init #f)  (ext? #f) (fin? #t))
       (let ((v (##sys#make-structure 'f64vector (alloc 'make-f64vector 8 len ext?))))
-	(when (and ext? fin?) (set-finalizer! v ext-free))
-	(if (not init)
-	    v
-	    (begin
-	      (check-int/flonum init 'make-f64vector)
-	      (unless (##core#inline "C_i_flonump" init)
-		(set! init (##core#inline_allocate ("C_a_u_i_int_to_flo" 4) init)) )
-	      (do ((i 0 (##core#inline "C_fixnum_plus" i 1)))
-		  ((##core#inline "C_fixnum_greater_or_equal_p" i len) v)
-		(##core#inline "C_u_i_f64vector_set" v i init) ) ) ) ) ) )
+        (when (and ext? fin?) (set-finalizer! v ext-free))
+        (if (not init)
+            v
+            (begin
+              (check-int/flonum init 'make-f64vector)
+              (unless (##core#inline "C_i_flonump" init)
+                (set! init (##core#inline_allocate ("C_a_u_i_int_to_flo" 4) init)) )
+              (do ((i 0 (##core#inline "C_fixnum_plus" i 1)))
+                  ((##core#inline "C_fixnum_greater_or_equal_p" i len) v)
+                (##core#inline "C_u_i_f64vector_set" v i init) ) ) ) ) ) )
 
   (set! make-c64vector
     (lambda (len #!optional (init #f)  (ext? #f) (fin? #t))
       (let ((v (##sys#make-structure 'c64vector (alloc 'make-c64vector 4 (fx* len 2) ext?))))
-	(when (and ext? fin?) (set-finalizer! v ext-free))
-	(if (not init)
-	    v
-	    (let ((len2 (fx* len 2)))
-	      (check-int/flonum init 'make-c64vector)
-	      (do ((i 0 (fx+ i 2)))
-		  ((fx>= i len2) v)
-		(##core#inline "C_u_i_f32vector_set" v i (real-part init))
-		(##core#inline "C_u_i_f32vector_set" v (fx+ i 1) (imag-part init))))))))
+        (when (and ext? fin?) (set-finalizer! v ext-free))
+        (if (not init)
+            v
+            (let ((len2 (fx* len 2))
+                  (rp (->f (real-part init)))
+                  (ip (->f (imag-part init))))
+              (check-int/flonum init 'make-c64vector)
+              (do ((i 0 (fx+ i 2)))
+                  ((fx>= i len2) v)
+                (##core#inline "C_u_i_f32vector_set" v i rp)
+                (##core#inline "C_u_i_f32vector_set" v (fx+ i 1) ip)))))))
 
   (set! make-c128vector
     (lambda (len #!optional (init #f)  (ext? #f) (fin? #t))
       (let ((v (##sys#make-structure 'c128vector (alloc 'make-c128vector 8 (fx* len 2) ext?))))
-	(when (and ext? fin?) (set-finalizer! v ext-free))
-	(if (not init)
-	    v
-	    (let ((len2 (fx* len 2)))
-	      (check-int/flonum init 'make-c128vector)
-	      (do ((i 0 (fx+ i 2)))
-		  ((fx>= i len2) v)
-		(##core#inline "C_u_i_f64vector_set" v i (real-part init))
-		(##core#inline "C_u_i_f64vector_set" v (fx+ i 1) (imag-part init)))))))))
+        (when (and ext? fin?) (set-finalizer! v ext-free))
+        (if (not init)
+            v
+            (let ((len2 (fx* len 2))
+                  (rp (->f (real-part init)))
+                  (ip (->f (imag-part init))))
+              (check-int/flonum init 'make-c128vector)
+              (do ((i 0 (fx+ i 2)))
+                  ((fx>= i len2) v)
+                (##core#inline "C_u_i_f64vector_set" v i rp)
+                (##core#inline "C_u_i_f64vector_set" v (fx+ i 1) ip))))))))
 
 
 ;;; Creating vectors from a list:
 
-(define-syntax list->NNNvector 
-  (er-macro-transformer 
+(define-syntax list->NNNvector
+  (er-macro-transformer
    (lambda (x r c)
      (let* ((tag (strip-syntax (cadr x)))
-	    (tagstr (symbol->string tag))
-	    (name (string->symbol (string-append "list->" tagstr)))
-	    (make (string->symbol (string-append "make-" tagstr)))
-	    (set (string->symbol (string-append tagstr "-set!"))))
+            (tagstr (symbol->string tag))
+            (name (string->symbol (string-append "list->" tagstr)))
+            (make (string->symbol (string-append "make-" tagstr)))
+            (set (string->symbol (string-append tagstr "-set!"))))
        `(define ,name
-	  (let ((,make ,make))
-	    (lambda (lst)
-	      (##sys#check-list lst ',tag)
-	      (let* ((n (##core#inline "C_i_length" lst))
-		     (v (,make n)) )
-		(do ((p lst (##core#inline "C_slot" p 1))
-		     (i 0 (##core#inline "C_fixnum_plus" i 1)) )
-		    ((##core#inline "C_eqp" p '()) v)
-		  (if (and (##core#inline "C_blockp" p) (##core#inline "C_pairp" p))
-		      (,set v i (##core#inline "C_slot" p 0))
-		      (##sys#error-not-a-proper-list lst ',name) ) ) ) )))))))
+          (let ((,make ,make))
+            (lambda (lst)
+              (##sys#check-list lst ',tag)
+              (let* ((n (##core#inline "C_i_length" lst))
+                     (v (,make n)) )
+                (do ((p lst (##core#inline "C_slot" p 1))
+                     (i 0 (##core#inline "C_fixnum_plus" i 1)) )
+                    ((##core#inline "C_eqp" p '()) v)
+                  (if (and (##core#inline "C_blockp" p) (##core#inline "C_pairp" p))
+                      (,set v i (##core#inline "C_slot" p 0))
+                      (##sys#error-not-a-proper-list lst ',name) ) ) ) )))))))
 
 (define list->u8vector ##sys#list->bytevector)
 
@@ -525,8 +541,40 @@ EOF
 (list->NNNvector s64vector)
 (list->NNNvector f32vector)
 (list->NNNvector f64vector)
-(list->NNNvector c64vector)
-(list->NNNvector c128vector)
+
+(define list->c64vector
+  (let ((real-part real-part)
+        (imag-part imag-part)
+        (make-c64vector make-c64vector))
+    (lambda (lst)
+      (##sys#check-list lst 'list->c64vector)
+      (let* ((n (##core#inline "C_i_length" lst))
+             (v (make-c64vector n)))
+        (do ((i 0 (##core#inline "C_u_fixnum_plus" i 2))
+             (lst lst (##core#inline "C_slot" lst 1)))
+            ((##core#inline "C_eqp" lst '()) v)
+            (let ((x (##core#inline "C_slot" lst 0)))
+              (##core#inline "C_u_i_f32vector_set" v i (->f (real-part x)))
+              (##core#inline "C_u_i_f32vector_set"
+               v (##core#inline "C_u_fixnum_plus" i 1)
+               (->f (imag-part x)))))))))
+
+(define list->c128vector
+  (let ((real-part real-part)
+        (imag-part imag-part)
+        (make-c128vector make-c128vector))
+    (lambda (lst)
+      (##sys#check-list lst 'list->c128vector)
+      (let* ((n (##core#inline "C_i_length" lst))
+             (v (make-c128vector n)))
+        (do ((i 0 (##core#inline "C_u_fixnum_plus" i 2))
+             (lst lst (##core#inline "C_slot" lst 1)))
+            ((##core#inline "C_eqp" lst '()) v)
+            (let ((x (##core#inline "C_slot" lst 0)))
+              (##core#inline "C_u_i_f64vector_set" v i (->f (real-part x)))
+              (##core#inline "C_u_i_f64vector_set"
+               v (##core#inline "C_u_fixnum_plus" i 1)
+               (->f (imag-part x)))))))))
 
 
 ;;; More constructors:
@@ -574,24 +622,24 @@ EOF
   (er-macro-transformer
    (lambda (x r c)
      (let* ((tag (symbol->string (strip-syntax (cadr x))))
-	    (alloc (and (pair? (cddr x)) (caddr x)))
-	    (name (string->symbol (string-append tag "->list"))))
+            (alloc (and (pair? (cddr x)) (caddr x)))
+            (name (string->symbol (string-append tag "->list"))))
        `(define (,name v)
-	  (##sys#check-structure v ',(string->symbol tag) ',name)
-	  (let ((len (##core#inline ,(string-append "C_u_i_" tag "_length") v)))
-	    (let loop ((i 0))
-	      (if (fx>= i len)
-		  '()
-		  (cons 
-		   ,(if alloc
-			`(##core#inline_allocate (,(string-append "C_a_u_i_" tag "_ref") ,alloc) v i)
-			`(##core#inline ,(string-append "C_u_i_" tag "_ref") v i))
-		   (loop (fx+ i 1)) ) ) ) ) ) ) )))
+          (##sys#check-structure v ',(string->symbol tag) ',name)
+          (let ((len (##core#inline ,(string-append "C_u_i_" tag "_length") v)))
+            (let loop ((i 0))
+              (if (fx>= i len)
+                  '()
+                  (cons
+                   ,(if alloc
+                        `(##core#inline_allocate (,(string-append "C_a_u_i_" tag "_ref") ,alloc) v i)
+                        `(##core#inline ,(string-append "C_u_i_" tag "_ref") v i))
+                   (loop (fx+ i 1)) ) ) ) ) ) ) )))
 
 (define (u8vector->list v)
   (##sys#check-bytevector v 'u8vector->list)
   (##sys#bytevector->list v))
-  
+
 (NNNvector->list s8vector)
 (NNNvector->list u16vector)
 (NNNvector->list s16vector)
diff --git a/tests/srfi-4-tests.scm b/tests/srfi-4-tests.scm
index 0675bd81..3bfe458d 100644
--- a/tests/srfi-4-tests.scm
+++ b/tests/srfi-4-tests.scm
@@ -119,3 +119,24 @@
       (let ((x (with-input-from-string (caar cs) read)))
         (unless (equal? x (cadar cs))
           (error "failed" x (cadar cs))))))
+
+;; complex vectors
+
+(define (dot v1 v2 n ref)
+  (do ((i 0 (add1 i))
+  	   (sum 0 (+ sum (* (ref v1 i) (ref v2 i)))))
+  	  ((>= i n) sum)))
+
+(assert
+  (= 1-i
+     (dot '#c64(1+i 1-i 0) '#c64(-i 0 2-i) 3 c64vector-ref)))
+(assert
+  (= 1-i
+     (dot '#c128(1+i 1-i 0) '#c128(-i 0 2-i) 3 c128vector-ref)))
+
+(assert
+  (= -1-i
+     (dot (c64vector 1+i 1-i 0) (c64vector 2+i 1-3i 0+2i) 3 c64vector-ref)))
+(assert
+  (= -1-i
+     (dot (c128vector 1+i 1-i 0) (c128vector 2+i 1-3i 0+2i) 3 c128vector-ref)))
Trap