diff options
author | Kaz Kylheku <kaz@kylheku.com> | 2017-06-11 11:06:38 -0700 |
---|---|---|
committer | Kaz Kylheku <kaz@kylheku.com> | 2017-06-11 11:06:38 -0700 |
commit | 9fca64292256f980e8cb15cea8c3e6cc7fd76374 (patch) | |
tree | 0bf7936c668cd69ce87b6b2735427b817e14bb7a /ffi.c | |
parent | 0687743dcfad79dba202b4411a5b51f6954cf3b2 (diff) | |
download | txr-9fca64292256f980e8cb15cea8c3e6cc7fd76374.tar.gz txr-9fca64292256f980e8cb15cea8c3e6cc7fd76374.tar.bz2 txr-9fca64292256f980e8cb15cea8c3e6cc7fd76374.zip |
ffi: handle sub operation in carray.
Thus, [ca 3..5] syntax works for slice extraction.
However, this works referentially, not by making a copy.
The extracted subarray points to the original memory,
until carray-dup is invoked on it.
* ffi.c (carray_sub): New function.
(ffi_init): carray-sub intrinsic registered.
* ffi.h (carray_sub): Declared.
* lib.c (sub): Handle carray via carray_sub.
* txr.1: Documented changes in sub.
Diffstat (limited to 'ffi.c')
-rw-r--r-- | ffi.c | 43 |
1 files changed, 43 insertions, 0 deletions
@@ -4558,6 +4558,48 @@ val carray_refset(val carray, val idx, val newval) } } +val carray_sub(val carray, val from, val to) +{ + struct carray *scry = carray_struct_checked(carray); + cnum ln = scry->nelem; + val len = num(ln); + + if (null_or_missing_p(from)) + from = zero; + + if (null_or_missing_p(to)) + to = len; + + if (minusp(to)) + to = plus(to, len); + + if (minusp(from)) + from = plus(from, len); + + { + cnum fn = c_num(from); + cnum tn = c_num(to); + cnum elsize = scry->eltft->size; + + if (fn < 0) + fn = 0; + + if (tn < 0) + tn = 0; + + if (tn > ln) + tn = ln; + + if (fn > ln) + fn = ln; + + if (tn < fn) + tn = fn; + + return make_carray(scry->eltype, scry->data + fn * elsize, tn - fn, carray); + } +} + static void carray_ensure_artype(val carray, struct carray *scry) { if (!scry->artype) { @@ -4730,6 +4772,7 @@ void ffi_init(void) reg_fun(intern(lit("list-carray"), user_package), func_n2o(list_carray, 1)); reg_fun(intern(lit("carray-ref"), user_package), func_n2(carray_ref)); reg_fun(intern(lit("carray-refset"), user_package), func_n3(carray_refset)); + reg_fun(intern(lit("carray-sub"), user_package), func_n3o(carray_sub, 1)); reg_fun(intern(lit("carray-get"), user_package), func_n1(carray_get)); reg_fun(intern(lit("carray-getz"), user_package), func_n1(carray_getz)); reg_fun(intern(lit("carray-put"), user_package), func_n2(carray_put)); |