summaryrefslogtreecommitdiffstats
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
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.
-rw-r--r--ffi.c43
-rw-r--r--ffi.h1
-rw-r--r--lib.c2
-rw-r--r--txr.191
4 files changed, 136 insertions, 1 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));
diff --git a/ffi.h b/ffi.h
index 2e88f167..4e45eaf2 100644
--- a/ffi.h
+++ b/ffi.h
@@ -104,6 +104,7 @@ val vec_carray(val carray, val null_term_p);
val list_carray(val carray, val null_term_p);
val carray_ref(val carray, val idx);
val carray_refset(val carray, val idx, val newval);
+val carray_sub(val carray, val from, val to);
val carray_get(val carray);
val carray_getz(val carray);
val carray_put(val array, val seq);
diff --git a/lib.c b/lib.c
index 6e14e618..4c345615 100644
--- a/lib.c
+++ b/lib.c
@@ -9179,6 +9179,8 @@ val sub(val seq, val from, val to)
case NIL:
return nil;
case COBJ:
+ if (seq->co.cls == carray_s)
+ return carray_sub(seq, from, to);
seq = nullify(seq);
/* fallthrough */
case CONS:
diff --git a/txr.1 b/txr.1
index 63515d87..d4755109 100644
--- a/txr.1
+++ b/txr.1
@@ -24971,6 +24971,13 @@ on Range Indexing\(emexplains the semantics of the range specification.
If the sequence is a list, the output sequence may share substructure
with the input sequence.
+If
+.meta sequence
+is a
+.code carray
+object, then the function behaves like
+.codn carray-sub .
+
When a
.code sub
form is used as a syntactic place, that place denotes a slice of
@@ -25535,7 +25542,12 @@ The
.code ref
and
.code refset
-functions perform array-like indexing into sequences.
+functions perform array-like indexing into sequences, as well as
+objects of type
+.code buf
+and
+.codn carray .
+
If the
.meta seq
parameter is a hash, then these functions perform
@@ -26289,6 +26301,16 @@ is processed, even if it contains
keys which are not in
.metn object .
+The
+.code select
+function also supports objects of type
+.codn carray ,
+in a manner similar to vectors. The indicated elements are extracted
+from the input object, and a new
+.code carray
+is returned whose storage is initialized by converting the extracted
+values back to the foreign representation.
+
.coNP Function @ in
.synb
.mets (in < sequence < key >> [ testfun <> [ keyfun ]])
@@ -28029,6 +28051,36 @@ Otherwise the original
.meta list
is returned.
+Conversion is supported to string and vector type.
+
+Conversion to a structure type is possible for structures. If
+.meta ref-sequence
+is an object of a structure type which has a static function
+.codn from-list ,
+then
+.code make-like
+calls that function, passing to it, and the resulting value is returned.
+.meta list
+and returns whatever value that function returns.
+
+If
+.meta ref-sequence
+is a
+.codn carray ,
+then
+.meta list
+is passed to the
+.code carray-list
+function, and the resulting value is returned. The second argument in the
+.code carray-list
+call is the element type taken from
+.metn ref-sequence .
+The third argument is
+.codn nil ,
+indicating that the resulting
+.code carray
+is not to be null terminated.
+
Note: the
.code make-like
function is a helper which supports the development of
@@ -56772,6 +56824,43 @@ then the expected string conversion semantics applies.
Both of these functions return
.metn carray .
+.coNP Function @ carray-sub
+.synb
+.mets (carray-sub < carray >> [ from <> [ to ]])
+.syne
+.desc
+The
+.code carray-sub
+function extracts a subrange of a
+.meta carray
+object, returning a new
+.code carray
+object denoting that subrange.
+
+The semantics of
+.meta from
+and
+.meta to
+work exactly like the corresponding arguments of the
+.code sub
+accessor, following the same conventions.
+
+The returned
+.code carray
+shares the array has the same element type as the original and
+shares the same array storage. If, subsequently, elements of the
+original array are modified which lie in the range, then the
+modifications will affect the previously returned subrange
+.codn carray .
+The returned
+.code carray
+references the original object, to ensure that as long as the returned object
+is reachable by the garbage collector, so is the original. This relationship
+can be severed by invoking
+.code carray-dup
+on the returned object, after which the two no longer share storage,
+and modifications in the original are not reflected in the subrange.
+
.SH* INTERACTIVE LISTENER
.SS* Overview