summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorKaz Kylheku <kaz@kylheku.com>2017-06-11 20:19:55 -0700
committerKaz Kylheku <kaz@kylheku.com>2017-06-11 20:19:55 -0700
commit082132f7d5d86068ab733f49fc4c43a9bd6157f1 (patch)
tree985bc3692395c4cedcdd98f84ea2349f03aab816
parent9fca64292256f980e8cb15cea8c3e6cc7fd76374 (diff)
downloadtxr-082132f7d5d86068ab733f49fc4c43a9bd6157f1.tar.gz
txr-082132f7d5d86068ab733f49fc4c43a9bd6157f1.tar.bz2
txr-082132f7d5d86068ab733f49fc4c43a9bd6157f1.zip
ffi: new function, carray-pun.
* ffi.c (carray_pun): New function. (ffi_init): Registered carray-pun intrinsic. * ffi.h (carray_pun): Declared. * txr.1: Documented.
-rw-r--r--ffi.c21
-rw-r--r--ffi.h1
-rw-r--r--txr.138
3 files changed, 60 insertions, 0 deletions
diff --git a/ffi.c b/ffi.c
index e73ced92..f85dec4e 100644
--- a/ffi.c
+++ b/ffi.c
@@ -4672,6 +4672,26 @@ val carray_putz(val carray, val seq)
return carray;
}
+val carray_pun(val carray, val type)
+{
+ val self = lit("carray-pun");
+ struct carray *scry = carray_struct_checked(carray);
+ struct txr_ffi_type *tft = ffi_type_struct(type);
+ cnum len = scry->nelem;
+ cnum elsize = scry->eltft->size;
+ cnum size = (ucnum) len * (ucnum) elsize;
+
+ if (tft->size == 0)
+ uw_throwf(error_s,
+ lit("~a: incomplete type ~s cannot be carray element"),
+ self, tft->syntax, nao);
+
+ if (len != 0 && size / elsize != len)
+ uw_throwf(error_s, lit("~a: array size overflow"), self, nao);
+
+ return make_carray(type, scry->data, size / tft->size, carray);
+}
+
void ffi_init(void)
{
prot1(&ffi_typedef_hash);
@@ -4777,6 +4797,7 @@ void ffi_init(void)
reg_fun(intern(lit("carray-getz"), user_package), func_n1(carray_getz));
reg_fun(intern(lit("carray-put"), user_package), func_n2(carray_put));
reg_fun(intern(lit("carray-putz"), user_package), func_n2(carray_putz));
+ reg_fun(intern(lit("carray-pun"), user_package), func_n2(carray_pun));
ffi_typedef_hash = make_hash(nil, nil, nil);
ffi_init_types();
ffi_init_extra_types();
diff --git a/ffi.h b/ffi.h
index 4e45eaf2..49efc83f 100644
--- a/ffi.h
+++ b/ffi.h
@@ -109,4 +109,5 @@ val carray_get(val carray);
val carray_getz(val carray);
val carray_put(val array, val seq);
val carray_putz(val array, val seq);
+val carray_pun(val carray, val type);
void ffi_init(void);
diff --git a/txr.1 b/txr.1
index d4755109..ba900fa1 100644
--- a/txr.1
+++ b/txr.1
@@ -56861,6 +56861,44 @@ can be severed by invoking
on the returned object, after which the two no longer share storage,
and modifications in the original are not reflected in the subrange.
+.coNP Function @ carray-pun
+.synb
+.mets (carray-sub < carray << type )
+.syne
+.desc
+The
+.code carray-pun
+creates a new
+.code carray
+object which provides an aliased view of the same data that is referenced by
+the original
+.meta carray
+object.
+
+The
+.meta type
+argument specifies the element type used by the returned aliasing array.
+
+The
+.code carray-pun
+function considers the byte size of the array, which is a product of
+the original length and element size. It then calculates how many elements of
+.meta type
+fit into this size. This value becomes the length of the aliasing array
+which is returned.
+
+Since the returned aliasing array and the original refer to the same
+storage, modifications performed in one view are reflected in the other.
+
+The aliasing array holds a reference to the original, so that as long as
+it is reachable by the garbage collector, so is the original.
+That relationship is severed if
+.code carray-dup
+is invoked on the aliasing array.
+
+The meaning of the aliasing depends entirely on the bitwise representations of
+the types involved.
+
.SH* INTERACTIVE LISTENER
.SS* Overview