~ chicken-core (master) /srfi-4.scm
Trap1;;;; srfi-4.scm - Homogeneous numeric vectors
2;
3; Copyright (c) 2008-2022, The CHICKEN Team
4; Copyright (c) 2000-2007, Felix L. Winkelmann
5; All rights reserved.
6;
7; Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following
8; conditions are met:
9;
10; Redistributions of source code must retain the above copyright notice, this list of conditions and the following
11; disclaimer.
12; Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following
13; disclaimer in the documentation and/or other materials provided with the distribution.
14; Neither the name of the author nor the names of its contributors may be used to endorse or promote
15; products derived from this software without specific prior written permission.
16;
17; THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS
18; OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY
19; AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDERS OR
20; CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
21; CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
22; SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
23; THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
24; OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
25; POSSIBILITY OF SUCH DAMAGE.
26
27
28(declare
29 (unit srfi-4)
30 (uses expand extras)
31 (disable-interrupts)
32 (not inline ##sys#user-print-hook)
33 (foreign-declare #<<EOF
34#define C_copy_subvector(to, from, start_to, start_from, bytes) \
35 (C_memcpy((C_char *)C_data_pointer(to) + C_unfix(start_to), (C_char *)C_data_pointer(from) + C_unfix(start_from), C_unfix(bytes)), \
36 C_SCHEME_UNDEFINED)
37EOF
38) )
39
40(module chicken.number-vector
41 (bytevector->f32vector bytevector->f32vector/shared
42 bytevector->f64vector bytevector->f64vector/shared
43 bytevector->s16vector bytevector->s16vector/shared
44 bytevector->s32vector bytevector->s32vector/shared
45 bytevector->s64vector bytevector->s64vector/shared
46 bytevector->s8vector bytevector->s8vector/shared
47 bytevector->u16vector bytevector->u16vector/shared
48 bytevector->u32vector bytevector->u32vector/shared
49 bytevector->u64vector bytevector->u64vector/shared
50 bytevector->c64vector bytevector->c64vector/shared
51 bytevector->c128vector bytevector->c128vector/shared
52 f32vector f32vector->bytevector f32vector->bytevector/shared f32vector->list
53 f32vector-length f32vector-ref f32vector-set! f32vector?
54 f64vector f64vector->bytevector f64vector->bytevector/shared f64vector->list
55 f64vector-length f64vector-ref f64vector-set! f64vector?
56 s8vector s8vector->bytevector s8vector->bytevector/shared s8vector->list
57 s8vector-length s8vector-ref s8vector-set! s8vector?
58 s16vector s16vector->bytevector s16vector->bytevector/shared s16vector->list
59 s16vector-length s16vector-ref s16vector-set! s16vector?
60 s32vector s32vector->bytevector s32vector->bytevector/shared s32vector->list
61 s32vector-length s32vector-ref s32vector-set! s32vector?
62 s64vector s64vector->bytevector s64vector->bytevector/shared s64vector->list
63 s64vector-length s64vector-ref s64vector-set! s64vector?
64 u8vector u8vector->list
65 u8vector-length u8vector-ref u8vector-set! u8vector?
66 u16vector u16vector->bytevector u16vector->bytevector/shared u16vector->list
67 u16vector-length u16vector-ref u16vector-set! u16vector?
68 u32vector u32vector->bytevector u32vector->bytevector/shared u32vector->list
69 u32vector-length u32vector-ref u32vector-set! u32vector?
70 u64vector u64vector->bytevector u64vector->bytevector/shared u64vector->list
71 u64vector-length u64vector-ref u64vector-set! u64vector?
72 c64vector c64vector->bytevector c64vector->bytevector/shared c64vector->list
73 c64vector-length c64vector-ref c64vector-set! c64vector?
74 c128vector c128vector->bytevector c128vector->bytevector/shared c128vector->list
75 c128vector-length c128vector-ref c128vector-set! c128vector?
76 list->f32vector list->f64vector list->s16vector list->s32vector
77 list->s64vector list->s8vector list->u16vector list->u32vector
78 list->u8vector list->u64vector list->c64vector list->c128vector
79 make-f32vector make-f64vector make-s16vector make-s32vector
80 make-s64vector make-s8vector make-u16vector make-u32vector
81 make-u64vector make-u8vector make-c64vector make-c128vector
82 number-vector? release-number-vector
83 subf32vector subf64vector subs16vector subs32vector subs64vector
84 subs8vector subu16vector subu8vector subu32vector subu64vector
85 subc64vector subc128vector)
86
87(import scheme
88 chicken.base
89 chicken.bitwise
90 chicken.bytevector
91 chicken.fixnum
92 chicken.foreign
93 chicken.gc
94 chicken.platform
95 chicken.syntax)
96
97(include "common-declarations.scm")
98
99
100;;; Helper routines:
101
102(define-inline (check-int/flonum x loc)
103 (unless (or (##core#inline "C_i_exact_integerp" x)
104 (##core#inline "C_i_flonump" x))
105 (##sys#error-hook (foreign-value "C_BAD_ARGUMENT_TYPE_NO_FLONUM_ERROR" int) loc x) ) )
106
107(define-inline (check-uint-length obj len loc)
108 (##sys#check-exact-uinteger obj loc)
109 (when (fx> (integer-length obj) len)
110 (##sys#error-hook
111 (foreign-value "C_BAD_ARGUMENT_TYPE_NUMERIC_RANGE_ERROR" int) loc obj)))
112
113(define-inline (check-int-length obj len loc)
114 (##sys#check-exact-integer obj loc)
115 (when (fx> (integer-length obj) (fx- len 1))
116 (##sys#error-hook
117 (foreign-value "C_BAD_ARGUMENT_TYPE_NUMERIC_RANGE_ERROR" int)
118 loc obj)))
119
120(define-syntax ->f
121 (syntax-rules ()
122 ((_ x)
123 (let ((tmp x))
124 (if (##core#inline "C_i_flonump" tmp)
125 tmp
126 (##core#inline_allocate ("C_a_u_i_int_to_flo" 4) tmp))))))
127
128;;; Get vector length:
129
130(define (u8vector-length x)
131 (##core#inline "C_i_bytevector_length" x))
132
133(define (s8vector-length x)
134 (##core#inline "C_i_s8vector_length" x))
135
136(define (u16vector-length x)
137 (##core#inline "C_i_u16vector_length" x))
138
139(define (s16vector-length x)
140 (##core#inline "C_i_s16vector_length" x))
141
142(define (u32vector-length x)
143 (##core#inline "C_i_u32vector_length" x))
144
145(define (s32vector-length x)
146 (##core#inline "C_i_s32vector_length" x))
147
148(define (u64vector-length x)
149 (##core#inline "C_i_u64vector_length" x))
150
151(define (s64vector-length x)
152 (##core#inline "C_i_s64vector_length" x))
153
154(define (f32vector-length x)
155 (##core#inline "C_i_f32vector_length" x))
156
157(define (f64vector-length x)
158 (##core#inline "C_i_f64vector_length" x))
159
160(define (c64vector-length x)
161 (##sys#check-structure x 'c64vector 'c64vector-length)
162 (fx/ (##core#inline "C_i_bytevector_length" (##sys#slot x 1)) 8))
163
164(define (c128vector-length x)
165 (##sys#check-structure x 'c128vector 'c128vector-length)
166 (fx/ (##core#inline "C_i_bytevector_length" (##sys#slot x 1)) 16))
167
168
169;;; Safe accessors:
170
171(define u8vector-set! bytevector-u8-set!)
172
173(define (s8vector-set! x i y)
174 (##core#inline "C_i_s8vector_set" x i y))
175
176(define (u16vector-set! x i y)
177 (##core#inline "C_i_u16vector_set" x i y))
178
179(define (s16vector-set! x i y)
180 (##core#inline "C_i_s16vector_set" x i y))
181
182(define (u32vector-set! x i y)
183 (##core#inline "C_i_u32vector_set" x i y))
184
185(define (s32vector-set! x i y)
186 (##core#inline "C_i_s32vector_set" x i y))
187
188(define (u64vector-set! x i y)
189 (##core#inline "C_i_u64vector_set" x i y))
190
191(define (s64vector-set! x i y)
192 (##core#inline "C_i_s64vector_set" x i y))
193
194(define (f32vector-set! x i y)
195 (##core#inline "C_i_f32vector_set" x i y))
196
197(define (f64vector-set! x i y)
198 (##core#inline "C_i_f64vector_set" x i y))
199
200(define (c64vector-set! x i y)
201 (##sys#check-structure x 'c64vector 'c64vector-set!)
202 (let* ((bv (##sys#slot x 1))
203 (len (fx/ (##core#inline "C_i_bytevector_length" bv) 8)))
204 (##sys#check-range i 0 len 'c64vector-set!)
205 (##sys#check-number y 'c64vector-set!)
206 (##core#inline "C_u_i_f32vector_set" x (fx/ i 2) (->f (real-part y)))
207 (##core#inline "C_u_i_f32vector_set" x (fx+ (fx/ i 2) 1) (->f (imag-part y)))))
208
209(define (c128vector-set! x i y)
210 (##sys#check-structure x 'c128vector 'c128vector-set!)
211 (let* ((bv (##sys#slot x 1))
212 (len (fx/ (##core#inline "C_i_bytevector_length" bv) 16)))
213 (##sys#check-range i 0 len 'c128vector-set!)
214 (##sys#check-number y 'c128vector-set!)
215 (##core#inline "C_u_i_f64vector_set" x (fx/ i 2) (->f (real-part y)))
216 (##core#inline "C_u_i_f64vector_set" x (fx+ (fx/ i 2) 1) (->f (imag-part y)))))
217
218(define u8vector-ref bytevector-u8-ref)
219
220(define s8vector-ref
221 (getter-with-setter
222 (lambda (x i) (##core#inline "C_i_s8vector_ref" x i))
223 s8vector-set!
224 "(chicken.number-vector#s8vector-ref v i)"))
225
226(define u16vector-ref
227 (getter-with-setter
228 (lambda (x i) (##core#inline "C_i_u16vector_ref" x i))
229 u16vector-set!
230 "(chicken.number-vector#u16vector-ref v i)"))
231
232(define s16vector-ref
233 (getter-with-setter
234 (lambda (x i) (##core#inline "C_i_s16vector_ref" x i))
235 s16vector-set!
236 "(chicken.number-vector#s16vector-ref v i)"))
237
238(define u32vector-ref
239 (getter-with-setter
240 (lambda (x i) (##core#inline_allocate ("C_a_i_u32vector_ref" 5) x i))
241 u32vector-set!
242 "(chicken.number-vector#u32vector-ref v i)"))
243
244(define s32vector-ref
245 (getter-with-setter
246 (lambda (x i) (##core#inline_allocate ("C_a_i_s32vector_ref" 5) x i))
247 s32vector-set!
248 "(chicken.number-vector#s32vector-ref v i)"))
249
250(define u64vector-ref
251 (getter-with-setter
252 (lambda (x i) (##core#inline_allocate ("C_a_i_u64vector_ref" 7) x i))
253 u64vector-set!
254 "(chicken.number-vector#u64vector-ref v i)"))
255
256(define s64vector-ref
257 (getter-with-setter
258 (lambda (x i) (##core#inline_allocate ("C_a_i_s64vector_ref" 7) x i))
259 s64vector-set!
260 "(chicken.number-vector#s64vector-ref v i)"))
261
262(define f32vector-ref
263 (getter-with-setter
264 (lambda (x i) (##core#inline_allocate ("C_a_i_f32vector_ref" 4) x i))
265 f32vector-set!
266 "(chicken.number-vector#f32vector-ref v i)"))
267
268(define f64vector-ref
269 (getter-with-setter
270 (lambda (x i) (##core#inline_allocate ("C_a_i_f64vector_ref" 4) x i))
271 f64vector-set!
272 "(chicken.number-vector#f64vector-ref v i)"))
273
274(define c64vector-ref
275 (getter-with-setter
276 (lambda (x i)
277 (##sys#check-structure x 'c64vector 'c64vector-ref)
278 (##sys#check-range i 0 (fx/ (##core#inline "C_i_bytevector_length" (##sys#slot x 1))
279 8) 'c64vector-ref)
280 (let ((p (fx/ i 2)))
281 (make-rectangular (##core#inline_allocate ("C_a_u_i_f32vector_ref" 4) x p)
282 (##core#inline_allocate ("C_a_u_i_f32vector_ref" 4) x (fx+ p 1)))))
283 c64vector-set!
284 "(chicken.number-vector#c64vector-ref v i)"))
285
286(define c128vector-ref
287 (getter-with-setter
288 (lambda (x i)
289 (##sys#check-structure x 'c128vector 'c128vector-ref)
290 (##sys#check-range i 0 (fx/ (##core#inline "C_i_bytevector_length" (##sys#slot x 1))
291 16) 'c128vector-ref)
292 (let ((p (fx/ i 2)))
293 (make-rectangular (##core#inline_allocate ("C_a_u_i_f64vector_ref" 4) x p)
294 (##core#inline_allocate ("C_a_u_i_f64vector_ref" 4) x (fx+ p 1)))))
295 c128vector-set!
296 "(chicken.number-vector#c128vector-ref v i)"))
297
298
299;;; Basic constructors:
300
301(define make-f32vector)
302(define make-f64vector)
303(define make-s16vector)
304(define make-s32vector)
305(define make-s64vector)
306(define make-s8vector)
307(define make-u8vector)
308(define make-u16vector)
309(define make-u32vector)
310(define make-u64vector)
311(define make-c64vector)
312(define make-c128vector)
313(define release-number-vector)
314
315(let* ((ext-alloc
316 (foreign-lambda* scheme-object ((size_t bytes))
317 "if (bytes > C_HEADER_SIZE_MASK) C_return(C_SCHEME_FALSE);"
318 "C_word *buf = (C_word *)C_malloc(bytes + sizeof(C_header));"
319 "if(buf == NULL) C_return(C_SCHEME_FALSE);"
320 "C_block_header_init(buf, C_make_header(C_BYTEVECTOR_TYPE, bytes));"
321 "C_return(buf);") )
322 (ext-free
323 (foreign-lambda* void ((scheme-object bv))
324 "C_free((void *)C_block_item(bv, 1));") )
325 (alloc
326 (lambda (loc elem-size elems ext?)
327 (##sys#check-fixnum elems loc)
328 (when (fx< elems 0) (##sys#error loc "size is negative" elems))
329 (let ((len (fx*? elems elem-size)))
330 (unless len (##sys#error "overflow - cannot allocate the required number of elements" elems))
331 (if ext?
332 (let ((bv (ext-alloc len)))
333 (or bv
334 (##sys#error loc "not enough memory - cannot allocate external number vector" len)) )
335 (##sys#allocate-bytevector len #f))))))
336
337 (set! release-number-vector
338 (lambda (v)
339 (if (number-vector? v)
340 (ext-free v)
341 (##sys#error 'release-number-vector "bad argument type - not a number vector" v)) ) )
342
343 (set! make-u8vector
344 (lambda (len #!optional (init #f) (ext? #f) (fin? #t))
345 (let ((v (alloc 'make-u8vector 1 len ext?)))
346 (when (and ext? fin?) (set-finalizer! v ext-free))
347 (if (not init)
348 v
349 (begin
350 (check-uint-length init 8 'make-u8vector)
351 (do ((i 0 (##core#inline "C_fixnum_plus" i 1)))
352 ((##core#inline "C_fixnum_greater_or_equal_p" i len) v)
353 (##core#inline "C_setsubbyte" v i init) ) ) ) ) ) )
354
355 (set! make-s8vector
356 (lambda (len #!optional (init #f) (ext? #f) (fin? #t))
357 (let ((v (##sys#make-structure 's8vector (alloc 'make-s8vector 1 len ext?))))
358 (when (and ext? fin?) (set-finalizer! v ext-free))
359 (if (not init)
360 v
361 (begin
362 (check-uint-length init 8 'make-s8vector)
363 (do ((i 0 (##core#inline "C_fixnum_plus" i 1)))
364 ((##core#inline "C_fixnum_greater_or_equal_p" i len) v)
365 (##core#inline "C_u_i_s8vector_set" v i init) ) ) ) ) ) )
366
367 (set! make-u16vector
368 (lambda (len #!optional (init #f) (ext? #f) (fin? #t))
369 (let ((v (##sys#make-structure 'u16vector (alloc 'make-u16vector 2 len ext?))))
370 (when (and ext? fin?) (set-finalizer! v ext-free))
371 (if (not init)
372 v
373 (begin
374 (check-uint-length init 16 'make-u16vector)
375 (do ((i 0 (##core#inline "C_fixnum_plus" i 1)))
376 ((##core#inline "C_fixnum_greater_or_equal_p" i len) v)
377 (##core#inline "C_u_i_u16vector_set" v i init) ) ) ) ) ) )
378
379 (set! make-s16vector
380 (lambda (len #!optional (init #f) (ext? #f) (fin? #t))
381 (let ((v (##sys#make-structure 's16vector (alloc 'make-s16vector 2 len ext?))))
382 (when (and ext? fin?) (set-finalizer! v ext-free))
383 (if (not init)
384 v
385 (begin
386 (check-int-length init 16 'make-s16vector)
387 (do ((i 0 (##core#inline "C_fixnum_plus" i 1)))
388 ((##core#inline "C_fixnum_greater_or_equal_p" i len) v)
389 (##core#inline "C_u_i_s16vector_set" v i init) ) ) ) ) ) )
390
391 (set! make-u32vector
392 (lambda (len #!optional (init #f) (ext? #f) (fin? #t))
393 (let ((v (##sys#make-structure 'u32vector (alloc 'make-u32vector 4 len ext?))))
394 (when (and ext? fin?) (set-finalizer! v ext-free))
395 (if (not init)
396 v
397 (begin
398 (check-uint-length init 32 'make-u32vector)
399 (do ((i 0 (##core#inline "C_fixnum_plus" i 1)))
400 ((##core#inline "C_fixnum_greater_or_equal_p" i len) v)
401 (##core#inline "C_u_i_u32vector_set" v i init) ) ) ) ) ) )
402
403 (set! make-u64vector
404 (lambda (len #!optional (init #f) (ext? #f) (fin? #t))
405 (let ((v (##sys#make-structure 'u64vector (alloc 'make-u64vector 8 len ext?))))
406 (when (and ext? fin?) (set-finalizer! v ext-free))
407 (if (not init)
408 v
409 (begin
410 (check-uint-length init 64 'make-u64vector)
411 (do ((i 0 (##core#inline "C_fixnum_plus" i 1)))
412 ((##core#inline "C_fixnum_greater_or_equal_p" i len) v)
413 (##core#inline "C_u_i_u64vector_set" v i init) ) ) ) ) ) )
414
415 (set! make-s32vector
416 (lambda (len #!optional (init #f) (ext? #f) (fin? #t))
417 (let ((v (##sys#make-structure 's32vector (alloc 'make-s32vector 4 len ext?))))
418 (when (and ext? fin?) (set-finalizer! v ext-free))
419 (if (not init)
420 v
421 (begin
422 (check-int-length init 32 'make-s32vector)
423 (do ((i 0 (##core#inline "C_fixnum_plus" i 1)))
424 ((##core#inline "C_fixnum_greater_or_equal_p" i len) v)
425 (##core#inline "C_u_i_s32vector_set" v i init) ) ) ) ) ) )
426
427 (set! make-s64vector
428 (lambda (len #!optional (init #f) (ext? #f) (fin? #t))
429 (let ((v (##sys#make-structure 's64vector (alloc 'make-s64vector 8 len ext?))))
430 (when (and ext? fin?) (set-finalizer! v ext-free))
431 (if (not init)
432 v
433 (begin
434 (check-int-length init 64 'make-s64vector)
435 (do ((i 0 (##core#inline "C_fixnum_plus" i 1)))
436 ((##core#inline "C_fixnum_greater_or_equal_p" i len) v)
437 (##core#inline "C_u_i_s64vector_set" v i init) ) ) ) ) ) )
438
439 (set! make-f32vector
440 (lambda (len #!optional (init #f) (ext? #f) (fin? #t))
441 (let ((v (##sys#make-structure 'f32vector (alloc 'make-f32vector 4 len ext?))))
442 (when (and ext? fin?) (set-finalizer! v ext-free))
443 (if (not init)
444 v
445 (begin
446 (check-int/flonum init 'make-f32vector)
447 (unless (##core#inline "C_i_flonump" init)
448 (set! init (##core#inline_allocate ("C_a_u_i_int_to_flo" 4) init)))
449 (do ((i 0 (##core#inline "C_fixnum_plus" i 1)))
450 ((##core#inline "C_fixnum_greater_or_equal_p" i len) v)
451 (##core#inline "C_u_i_f32vector_set" v i init) ) ) ) ) ) )
452
453 (set! make-f64vector
454 (lambda (len #!optional (init #f) (ext? #f) (fin? #t))
455 (let ((v (##sys#make-structure 'f64vector (alloc 'make-f64vector 8 len ext?))))
456 (when (and ext? fin?) (set-finalizer! v ext-free))
457 (if (not init)
458 v
459 (begin
460 (check-int/flonum init 'make-f64vector)
461 (unless (##core#inline "C_i_flonump" init)
462 (set! init (##core#inline_allocate ("C_a_u_i_int_to_flo" 4) init)) )
463 (do ((i 0 (##core#inline "C_fixnum_plus" i 1)))
464 ((##core#inline "C_fixnum_greater_or_equal_p" i len) v)
465 (##core#inline "C_u_i_f64vector_set" v i init) ) ) ) ) ) )
466
467 (set! make-c64vector
468 (lambda (len #!optional (init #f) (ext? #f) (fin? #t))
469 (let ((v (##sys#make-structure 'c64vector (alloc 'make-c64vector 4 (fx* len 2) ext?))))
470 (when (and ext? fin?) (set-finalizer! v ext-free))
471 (if (not init)
472 v
473 (let ((len2 (fx* len 2)))
474 (check-int/flonum init 'make-c64vector)
475 (do ((i 0 (fx+ i 2)))
476 ((fx>= i len2) v)
477 (##core#inline "C_u_i_f32vector_set" v i (real-part init))
478 (##core#inline "C_u_i_f32vector_set" v (fx+ i 1) (imag-part init))))))))
479
480 (set! make-c128vector
481 (lambda (len #!optional (init #f) (ext? #f) (fin? #t))
482 (let ((v (##sys#make-structure 'c128vector (alloc 'make-c128vector 8 (fx* len 2) ext?))))
483 (when (and ext? fin?) (set-finalizer! v ext-free))
484 (if (not init)
485 v
486 (let ((len2 (fx* len 2)))
487 (check-int/flonum init 'make-c128vector)
488 (do ((i 0 (fx+ i 2)))
489 ((fx>= i len2) v)
490 (##core#inline "C_u_i_f64vector_set" v i (real-part init))
491 (##core#inline "C_u_i_f64vector_set" v (fx+ i 1) (imag-part init)))))))))
492
493
494;;; Creating vectors from a list:
495
496(define-syntax list->NNNvector
497 (er-macro-transformer
498 (lambda (x r c)
499 (let* ((tag (strip-syntax (cadr x)))
500 (tagstr (symbol->string tag))
501 (name (string->symbol (string-append "list->" tagstr)))
502 (make (string->symbol (string-append "make-" tagstr)))
503 (set (string->symbol (string-append tagstr "-set!"))))
504 `(define ,name
505 (let ((,make ,make))
506 (lambda (lst)
507 (##sys#check-list lst ',tag)
508 (let* ((n (##core#inline "C_i_length" lst))
509 (v (,make n)) )
510 (do ((p lst (##core#inline "C_slot" p 1))
511 (i 0 (##core#inline "C_fixnum_plus" i 1)) )
512 ((##core#inline "C_eqp" p '()) v)
513 (if (and (##core#inline "C_blockp" p) (##core#inline "C_pairp" p))
514 (,set v i (##core#inline "C_slot" p 0))
515 (##sys#error-not-a-proper-list lst ',name) ) ) ) )))))))
516
517(define list->u8vector ##sys#list->bytevector)
518
519(list->NNNvector s8vector)
520(list->NNNvector u16vector)
521(list->NNNvector s16vector)
522(list->NNNvector u32vector)
523(list->NNNvector s32vector)
524(list->NNNvector u64vector)
525(list->NNNvector s64vector)
526(list->NNNvector f32vector)
527(list->NNNvector f64vector)
528(list->NNNvector c64vector)
529(list->NNNvector c128vector)
530
531
532;;; More constructors:
533
534(define u8vector
535 (lambda xs (list->u8vector xs)) )
536
537(define s8vector
538 (lambda xs (list->s8vector xs)) )
539
540(define u16vector
541 (lambda xs (list->u16vector xs)) )
542
543(define s16vector
544 (lambda xs (list->s16vector xs)) )
545
546(define u32vector
547 (lambda xs (list->u32vector xs)) )
548
549(define s32vector
550 (lambda xs (list->s32vector xs)) )
551
552(define u64vector
553 (lambda xs (list->u64vector xs)) )
554
555(define s64vector
556 (lambda xs (list->s64vector xs)) )
557
558(define f32vector
559 (lambda xs (list->f32vector xs)) )
560
561(define f64vector
562 (lambda xs (list->f64vector xs)) )
563
564(define c64vector
565 (lambda xs (list->c64vector xs)) )
566
567(define c128vector
568 (lambda xs (list->c128vector xs)) )
569
570
571;;; Creating lists from a vector:
572
573(define-syntax NNNvector->list
574 (er-macro-transformer
575 (lambda (x r c)
576 (let* ((tag (symbol->string (strip-syntax (cadr x))))
577 (alloc (and (pair? (cddr x)) (caddr x)))
578 (name (string->symbol (string-append tag "->list"))))
579 `(define (,name v)
580 (##sys#check-structure v ',(string->symbol tag) ',name)
581 (let ((len (##core#inline ,(string-append "C_u_i_" tag "_length") v)))
582 (let loop ((i 0))
583 (if (fx>= i len)
584 '()
585 (cons
586 ,(if alloc
587 `(##core#inline_allocate (,(string-append "C_a_u_i_" tag "_ref") ,alloc) v i)
588 `(##core#inline ,(string-append "C_u_i_" tag "_ref") v i))
589 (loop (fx+ i 1)) ) ) ) ) ) ) )))
590
591(define (u8vector->list v)
592 (##sys#check-bytevector v 'u8vector->list)
593 (##sys#bytevector->list v))
594
595(NNNvector->list s8vector)
596(NNNvector->list u16vector)
597(NNNvector->list s16vector)
598;; The alloc amounts here are for 32-bit words; this over-allocates on 64-bits
599(NNNvector->list u32vector 6)
600(NNNvector->list s32vector 6)
601(NNNvector->list u64vector 7)
602(NNNvector->list s64vector 7)
603(NNNvector->list f32vector 4)
604(NNNvector->list f64vector 4)
605
606(define c64vector->list
607 (let ((c64vector-length c64vector-length)
608 (c64vector-ref c64vector-ref))
609 (lambda (v)
610 (##sys#check-structure v 'c64vector 'c64vector->list)
611 (let ((len (c64vector-length v)))
612 (let loop ((i 0))
613 (if (fx>= i len)
614 '()
615 (cons (c64vector-ref v i)
616 (loop (fx+ i 1)) ) ) ) ))))
617
618(define c128vector->list
619 (let ((c128vector-length c128vector-length)
620 (c128vector-ref c128vector-ref))
621 (lambda (v)
622 (##sys#check-structure v 'c128vector 'c128vector->list)
623 (let ((len (c128vector-length v)))
624 (let loop ((i 0))
625 (if (fx>= i len)
626 '()
627 (cons (c128vector-ref v i)
628 (loop (fx+ i 1)) ) ) ) ) )))
629
630
631;;; Predicates:
632
633(define (u8vector? x) (and (##core#inline "C_blockp" x) (##core#inline "C_bytevectorp" x)))
634(define (s8vector? x) (and (##core#inline "C_blockp" x) (##core#inline "C_i_s8vectorp" x)))
635(define (u16vector? x) (and (##core#inline "C_blockp" x) (##core#inline "C_i_u16vectorp" x)))
636(define (s16vector? x) (and (##core#inline "C_blockp" x) (##core#inline "C_i_s16vectorp" x)))
637(define (u32vector? x) (and (##core#inline "C_blockp" x) (##core#inline "C_i_u32vectorp" x)))
638(define (s32vector? x) (and (##core#inline "C_blockp" x) (##core#inline "C_i_s32vectorp" x)))
639(define (u64vector? x) (and (##core#inline "C_blockp" x) (##core#inline "C_i_u64vectorp" x)))
640(define (s64vector? x) (and (##core#inline "C_blockp" x) (##core#inline "C_i_s64vectorp" x)))
641(define (f32vector? x) (and (##core#inline "C_blockp" x) (##core#inline "C_i_f32vectorp" x)))
642(define (f64vector? x) (and (##core#inline "C_blockp" x) (##core#inline "C_i_f64vectorp" x)))
643(define (c64vector? x) (and (##core#inline "C_blockp" x) (##core#inline "C_i_structurep" x 'c64vector)))
644(define (c128vector? x) (and (##core#inline "C_blockp" x) (##core#inline "C_i_structurep" x 'c128vector)))
645
646;; Catch-all predicate
647(define (number-vector? x)
648 (or (bytevector? x) (##sys#srfi-4-vector? x)))
649
650;;; Accessing the packed bytevector:
651
652(define (pack tag loc)
653 (lambda (v)
654 (##sys#check-structure v tag loc)
655 (##sys#slot v 1) ) )
656
657(define (pack-copy tag loc)
658 (lambda (v)
659 (##sys#check-structure v tag loc)
660 (let* ((old (##sys#slot v 1))
661 (new (##sys#make-bytevector (##sys#size old))))
662 (##core#inline "C_copy_block" old new) ) ) )
663
664(define (unpack tag sz loc)
665 (lambda (str)
666 (##sys#check-bytevector str loc)
667 (let ((len (##sys#size str)))
668 (if (or (eq? #t sz)
669 (eq? 0 (##core#inline "C_fixnum_modulo" len sz)))
670 (##sys#make-structure tag str)
671 (##sys#error loc "bytevector does not have correct size for packing" tag len sz) ) ) ) )
672
673(define (unpack-copy tag sz loc)
674 (lambda (str)
675 (##sys#check-bytevector str loc)
676 (let* ((len (##sys#size str))
677 (new (##sys#make-bytevector len)))
678 (if (or (eq? #t sz)
679 (eq? 0 (##core#inline "C_fixnum_modulo" len sz)))
680 (##sys#make-structure
681 tag
682 (##core#inline "C_copy_block" str new) )
683 (##sys#error loc "bytevector does not have correct size for packing" tag len sz) ) ) ) )
684
685(define s8vector->bytevector/shared (pack 's8vector 's8vector->bytevector/shared))
686(define u16vector->bytevector/shared (pack 'u16vector 'u16vector->bytevector/shared))
687(define s16vector->bytevector/shared (pack 's16vector 's16vector->bytevector/shared))
688(define u32vector->bytevector/shared (pack 'u32vector 'u32vector->bytevector/shared))
689(define s32vector->bytevector/shared (pack 's32vector 's32vector->bytevector/shared))
690(define u64vector->bytevector/shared (pack 'u64vector 'u64vector->bytevector/shared))
691(define s64vector->bytevector/shared (pack 's64vector 's64vector->bytevector/shared))
692(define f32vector->bytevector/shared (pack 'f32vector 'f32vector->bytevector/shared))
693(define f64vector->bytevector/shared (pack 'f64vector 'f64vector->bytevector/shared))
694(define c64vector->bytevector/shared (pack 'c64vector 'c64vector->bytevector/shared))
695(define c128vector->bytevector/shared (pack 'c128vector 'c128vector->bytevector/shared))
696
697(define s8vector->bytevector (pack-copy 's8vector 's8vector->bytevector))
698(define u16vector->bytevector (pack-copy 'u16vector 'u16vector->bytevector))
699(define s16vector->bytevector (pack-copy 's16vector 's16vector->bytevector))
700(define u32vector->bytevector (pack-copy 'u32vector 'u32vector->bytevector))
701(define s32vector->bytevector (pack-copy 's32vector 's32vector->bytevector))
702(define u64vector->bytevector (pack-copy 'u64vector 'u64vector->bytevector))
703(define s64vector->bytevector (pack-copy 's64vector 's64vector->bytevector))
704(define f32vector->bytevector (pack-copy 'f32vector 'f32vector->bytevector))
705(define f64vector->bytevector (pack-copy 'f64vector 'f64vector->bytevector))
706(define c64vector->bytevector (pack-copy 'c64vector 'c64vector->bytevector))
707(define c128vector->bytevector (pack-copy 'c128vector 'c128vector->bytevector))
708
709(define bytevector->s8vector/shared (unpack 's8vector #t 'bytevector->s8vector/shared))
710(define bytevector->u16vector/shared (unpack 'u16vector 2 'bytevector->u16vector/shared))
711(define bytevector->s16vector/shared (unpack 's16vector 2 'bytevector->s16vector/shared))
712(define bytevector->u32vector/shared (unpack 'u32vector 4 'bytevector->u32vector/shared))
713(define bytevector->s32vector/shared (unpack 's32vector 4 'bytevector->s32vector/shared))
714(define bytevector->u64vector/shared (unpack 'u64vector 4 'bytevector->u64vector/shared))
715(define bytevector->s64vector/shared (unpack 's64vector 4 'bytevector->s64vector/shared))
716(define bytevector->f32vector/shared (unpack 'f32vector 4 'bytevector->f32vector/shared))
717(define bytevector->f64vector/shared (unpack 'f64vector 8 'bytevector->f64vector/shared))
718(define bytevector->c64vector/shared (unpack 'c64vector 8 'bytevector->c64vector/shared))
719(define bytevector->c128vector/shared (unpack 'c128vector 16 'bytevector->c128vector/shared))
720
721(define bytevector->s8vector (unpack-copy 's8vector #t 'bytevector->s8vector))
722(define bytevector->u16vector (unpack-copy 'u16vector 2 'bytevector->u16vector))
723(define bytevector->s16vector (unpack-copy 's16vector 2 'bytevector->s16vector))
724(define bytevector->u32vector (unpack-copy 'u32vector 4 'bytevector->u32vector))
725(define bytevector->s32vector (unpack-copy 's32vector 4 'bytevector->s32vector))
726(define bytevector->u64vector (unpack-copy 'u64vector 4 'bytevector->u64vector))
727(define bytevector->s64vector (unpack-copy 's64vector 4 'bytevector->s64vector))
728(define bytevector->f32vector (unpack-copy 'f32vector 4 'bytevector->f32vector))
729(define bytevector->f64vector (unpack-copy 'f64vector 8 'bytevector->f64vector))
730(define bytevector->c64vector (unpack-copy 'c64vector 8 'bytevector->c64vector))
731(define bytevector->c128vector (unpack-copy 'c128vector 16 'bytevector->c128vector))
732
733;;; Subvectors:
734
735(define (subnvector v t es from to loc)
736 (##sys#check-structure v t loc)
737 (let* ([bv (##sys#slot v 1)]
738 [len (##sys#size bv)]
739 [ilen (##core#inline "C_u_fixnum_divide" len es)] )
740 (##sys#check-range/including from 0 ilen loc)
741 (##sys#check-range/including to 0 ilen loc)
742 (let* ([size2 (fx* es (fx- to from))]
743 [bv2 (##sys#allocate-bytevector size2 #f)] )
744 (let ([v (##sys#make-structure t bv2)])
745 (##core#inline "C_copy_subvector" bv2 bv 0 (fx* from es) size2)
746 v) ) ) )
747
748(define (subu8vector v from to)
749 (##sys#check-bytevector v 'subu8vector)
750 (let ((n (##sys#size v)))
751 (##sys#check-range/including from 0 n 'subu8vector)
752 (##sys#check-range/including to 0 n 'subu8vector)
753 (bytevector-copy v from to)))
754
755(define (subu16vector v from to) (subnvector v 'u16vector 2 from to 'subu16vector))
756(define (subu32vector v from to) (subnvector v 'u32vector 4 from to 'subu32vector))
757(define (subu64vector v from to) (subnvector v 'u64vector 8 from to 'subu64vector))
758(define (subs8vector v from to) (subnvector v 's8vector 1 from to 'subs8vector))
759(define (subs16vector v from to) (subnvector v 's16vector 2 from to 'subs16vector))
760(define (subs32vector v from to) (subnvector v 's32vector 4 from to 'subs32vector))
761(define (subs64vector v from to) (subnvector v 's64vector 8 from to 'subs64vector))
762(define (subf32vector v from to) (subnvector v 'f32vector 4 from to 'subf32vector))
763(define (subf64vector v from to) (subnvector v 'f64vector 8 from to 'subf64vector))
764(define (subc64vector v from to) (subnvector v 'c64vector 8 from to 'subc64vector))
765(define (subc128vector v from to) (subnvector v 'c128vector 16 from to 'subc128vector))
766
767) ; module chicken.number-vector
768
769(module srfi-4
770 (f32vector f32vector->list
771 f32vector-length f32vector-ref f32vector-set! f32vector?
772 f64vector f64vector->list
773 f64vector-length f64vector-ref f64vector-set! f64vector?
774 s8vector s8vector->list
775 s8vector-length s8vector-ref s8vector-set! s8vector?
776 s16vector s16vector->list
777 s16vector-length s16vector-ref s16vector-set! s16vector?
778 s32vector s32vector->list
779 s32vector-length s32vector-ref s32vector-set! s32vector?
780 s64vector s64vector->list
781 s64vector-length s64vector-ref s64vector-set! s64vector?
782 u8vector u8vector->list
783 u8vector-length u8vector-ref u8vector-set! u8vector?
784 u16vector u16vector->list
785 u16vector-length u16vector-ref u16vector-set! u16vector?
786 u32vector u32vector->list
787 u32vector-length u32vector-ref u32vector-set! u32vector?
788 u64vector u64vector->list
789 u64vector-length u64vector-ref u64vector-set! u64vector?
790 list->f32vector list->f64vector list->s16vector list->s32vector
791 list->s64vector list->s8vector list->u16vector list->u32vector
792 list->u8vector list->u64vector
793 make-f32vector make-f64vector make-s16vector make-s32vector
794 make-s64vector make-s8vector make-u16vector make-u32vector
795 make-u64vector make-u8vector)
796(import (chicken number-vector)))
797
798
799;;; Read syntax:
800
801(import scheme (chicken number-vector))
802
803(set! ##sys#user-read-hook
804 (let ((old-hook ##sys#user-read-hook)
805 (consers (list 'u8 chicken.number-vector#list->u8vector
806 's8 chicken.number-vector#list->s8vector
807 'u16 chicken.number-vector#list->u16vector
808 's16 chicken.number-vector#list->s16vector
809 'u32 chicken.number-vector#list->u32vector
810 's32 chicken.number-vector#list->s32vector
811 'u64 chicken.number-vector#list->u64vector
812 's64 chicken.number-vector#list->s64vector
813 'f32 chicken.number-vector#list->f32vector
814 'f64 chicken.number-vector#list->f64vector
815 'c64 chicken.number-vector#list->c64vector
816 'c128 chicken.number-vector#list->c128vector) ) )
817 (lambda (char port)
818 (if (memq char '(#\u #\s #\f #\c))
819 (let* ((x (##sys#read port ##sys#default-read-info-hook))
820 (tag (and (symbol? x) x)) )
821 (cond ((or (eq? tag 'f) (eq? tag 'false)) #f)
822 ((memq tag consers) =>
823 (lambda (c)
824 (let ((d (##sys#read-numvector-data port)))
825 (cond ((or (null? d) (pair? d))
826 ((cadr c) (##sys#canonicalize-number-list! d)))
827 ((eq? tag 'u8)
828 ;; reuse already created bytevector
829 (##core#inline "C_chop_bv" (##sys#slot d 0)))
830 (else
831 ((cadr c) (##sys#string->list d)))))))
832 (else (##sys#read-error port "invalid sharp-sign read syntax" tag)) ) )
833 (old-hook char port) ) ) ) )
834
835
836;;; Printing:
837
838(set! ##sys#user-print-hook
839 (let ((old-hook ##sys#user-print-hook))
840 (lambda (x readable port)
841 (let ((tag (assq (##core#inline "C_slot" x 0)
842 `((u8vector u8 ,chicken.number-vector#u8vector->list)
843 (s8vector s8 ,chicken.number-vector#s8vector->list)
844 (u16vector u16 ,chicken.number-vector#u16vector->list)
845 (s16vector s16 ,chicken.number-vector#s16vector->list)
846 (u32vector u32 ,chicken.number-vector#u32vector->list)
847 (s32vector s32 ,chicken.number-vector#s32vector->list)
848 (u64vector u64 ,chicken.number-vector#u64vector->list)
849 (s64vector s64 ,chicken.number-vector#s64vector->list)
850 (f32vector f32 ,chicken.number-vector#f32vector->list)
851 (f64vector f64 ,chicken.number-vector#f64vector->list)
852 (c64vector c64 ,chicken.number-vector#c64vector->list)
853 (c128vector c128 ,chicken.number-vector#c128vector->list)) ) ) )
854 (cond (tag
855 (##sys#print #\# #f port)
856 (##sys#print (cadr tag) #f port)
857 (##sys#print ((caddr tag) x) #t port) )
858 (else (old-hook x readable port)) ) ) ) ) )