summaryrefslogtreecommitdiffstats
path: root/ffi.c
diff options
context:
space:
mode:
authorKaz Kylheku <kaz@kylheku.com>2017-06-11 11:06:38 -0700
committerKaz Kylheku <kaz@kylheku.com>2017-06-11 11:06:38 -0700
commit9fca64292256f980e8cb15cea8c3e6cc7fd76374 (patch)
tree0bf7936c668cd69ce87b6b2735427b817e14bb7a /ffi.c
parent0687743dcfad79dba202b4411a5b51f6954cf3b2 (diff)
downloadtxr-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.c43
1 files changed, 43 insertions, 0 deletions
diff --git a/ffi.c b/ffi.c
index 1a40dcbb..e73ced92 100644
--- a/ffi.c
+++ b/ffi.c
@@ -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));