diff options
author | Kaz Kylheku <kaz@kylheku.com> | 2017-06-11 11:03:40 -0700 |
---|---|---|
committer | Kaz Kylheku <kaz@kylheku.com> | 2017-06-11 11:03:40 -0700 |
commit | 0687743dcfad79dba202b4411a5b51f6954cf3b2 (patch) | |
tree | 870fa9b01025fc28c5171c55fb1bb62278ee390e | |
parent | 05e9ac4bd7a26c6c5b5979efca64260f7d38970c (diff) | |
download | txr-0687743dcfad79dba202b4411a5b51f6954cf3b2.tar.gz txr-0687743dcfad79dba202b4411a5b51f6954cf3b2.tar.bz2 txr-0687743dcfad79dba202b4411a5b51f6954cf3b2.zip |
ffi: support sel operation on carray.
Thus (select ca '(0 3 4 ...)) works and so does the
sytnax [ca '(0 3 4 ...)]. This is inefficiently implemented.
The selected elements are extracted to a list which is then
converted to a carray of the same kind agan.
* ffi.c (carray_list): New function.
(ffi_init): Register carray-list intrinsic.
* ffi.h (carray_list): Declared.
* lib.c (make_like): Add carray case, so we can turn
a list into a carray based on an example carray.
This uses carray_list, with the type pulled from the
original carray. The target isn't null terminated.
(sel): Handle carray via vector case.
* txr.1: Document changes in select and make-like.
-rw-r--r-- | ffi.c | 18 | ||||
-rw-r--r-- | ffi.h | 1 | ||||
-rw-r--r-- | lib.c | 5 | ||||
-rw-r--r-- | txr.1 | 25 |
4 files changed, 42 insertions, 7 deletions
@@ -4425,6 +4425,23 @@ val carray_vec(val vec, val type, val null_term_p) return carray; } +val carray_list(val list, val type, val null_term_p) +{ + val nt_p = default_null_arg(null_term_p); + val len = if3(nt_p, succ(length(list)), length(list)); + val carray = carray_blank(len, type); + cnum i; + + (void) c_num(len); + + for (i = 0; !endp(list); list = cdr(list), i++) { + val el = car(list); + carray_refset(carray, num_fast(i), el); + } + + return carray; +} + val carray_blank(val nelem, val type) { val self = lit("carray-blank"); @@ -4704,6 +4721,7 @@ void ffi_init(void) reg_fun(intern(lit("carray-type"), user_package), func_n1(carray_type)); reg_fun(intern(lit("length-carray"), user_package), func_n1(length_carray)); reg_fun(intern(lit("carray-vec"), user_package), func_n3o(carray_vec, 2)); + reg_fun(intern(lit("carray-list"), user_package), func_n3o(carray_list, 2)); reg_fun(intern(lit("carray-blank"), user_package), func_n2(carray_blank)); reg_fun(intern(lit("carray-buf"), user_package), func_n2(carray_buf)); reg_fun(intern(lit("carray-buf-sync"), user_package), func_n1(carray_buf_sync)); @@ -95,6 +95,7 @@ val carray_type(val carray); val length_carray(val carray); mem_t *carray_ptr(val carray, val type, val self); val carray_vec(val vec, val type, val null_term_p); +val carray_list(val list, val type, val null_term_p); val carray_blank(val nelem, val type); val carray_buf(val buf, val type); val carray_buf_sync(val carray); @@ -718,6 +718,8 @@ val make_like(val list, val thatobj) if (from_list_meth) return funcall1(from_list_meth, list); } + if (thatobj->co.cls == carray_s) + return carray_list(list, carray_type(thatobj), nil); break; case NIL: case CONS: @@ -9633,6 +9635,8 @@ val sel(val seq_in, val where_in) return newhash; } + if (seq->co.cls == carray_s) + goto carray; /* fallthrough */ case CONS: case LCONS: @@ -9650,6 +9654,7 @@ val sel(val seq_in, val where_in) } } break; + carray: default: { val len = length(seq); @@ -56143,15 +56143,18 @@ in order to extract the return value of foreign function calls, and by the FFI callback mechanism to extract the arguments coming into a callback. -.coNP Function @ carray-vec +.coNP Functions @ carray-vec and @ carray-list .synb .mets (carray-vec < vec < type <> [ null-term-p ]) +.mets (carray-list < list < type <> [ null-term-p ]) .syne .desc The .code carray-vec -function allocates storage for the representation of a foreign array, and -returns a +and +.code carray-list +functions allocate storage for the representation of a foreign array, and +return a .code carray object which holds a pointer to that storage. @@ -56162,9 +56165,11 @@ is retained as the .code carray object's element type. -Prior to returning, the function +Prior to returning, the functions initializes the foreign array by converting the elements of .meta vec +or, respectively, +.meta list into elements of the foreign array. The conversion is performed using the put semantics of .metn type , @@ -56174,6 +56179,8 @@ The length of the returned .code carray is determined from the length of .meta vec +or +.meta list and from the value of the Boolean argument .metn null-term-p . @@ -56183,8 +56190,10 @@ is .codn nil , then the length of the .code carray -is the same as that of -.metn vec . +is the same as that of the input +.meta vec +or +.metn list . A true value of .meta null-term-p @@ -56192,7 +56201,9 @@ indicates null termination. This causes the length of the .code carray to be one greater than that of -.metn vec , +.meta vec +or +.metn list , and the extra element allocated to the foreign array is filled with zero bytes. .coNP Function @ carray-blank |