summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--ffi.c19
-rw-r--r--txr.134
2 files changed, 48 insertions, 5 deletions
diff --git a/ffi.c b/ffi.c
index 8d702c26..789b63f9 100644
--- a/ffi.c
+++ b/ffi.c
@@ -124,7 +124,7 @@ val closure_s;
val sbit_s, ubit_s; /* bit_s is in arith.c */
-val enum_s, enumed_s;
+val enum_s, enumed_s, elemtype_s;
val align_s;
@@ -3568,6 +3568,22 @@ val ffi_type_compile(val syntax)
uw_throwf(error_s, lit("~a: invalid ~s syntax"), self, sym, nao);
return type;
+ } else if (sym == elemtype_s) {
+ val args = cdr(syntax);
+ if (!consp(args) || cdr(args)) {
+ uw_throwf(error_s, lit("~a: one argument required"), self, qref_s, nao);
+ } else {
+ val expr = car(args);
+ val type = ffi_type_compile(expr);
+ struct txr_ffi_type *tft = ffi_type_struct_checked(self, type);
+
+ if (!tft->eltype) {
+ uw_throwf(error_s, lit("~a: ~s isn't an array, pointer or enum"),
+ self, type, nao);
+ }
+
+ return tft->eltype;
+ }
}
uw_throwf(error_s, lit("~a: unrecognized type operator: ~s"),
@@ -5654,6 +5670,7 @@ void ffi_init(void)
bit_s = intern(lit("bit"), user_package);
enum_s = intern(lit("enum"), user_package);
enumed_s = intern(lit("enumed"), user_package);
+ elemtype_s = intern(lit("elemtype"), user_package);
align_s = intern(lit("align"), user_package);
bool_s = intern(lit("bool"), user_package);
ffi_type_s = intern(lit("ffi-type"), user_package);
diff --git a/txr.1 b/txr.1
index 47d9c084..3f46cabe 100644
--- a/txr.1
+++ b/txr.1
@@ -63014,6 +63014,24 @@ can be written as
.code S.M.N
instead.
+.coNP FFI type @ elemtype
+.synb
+.mets (elemtype << type )
+.syne
+.desc
+The FFI type operator
+.code elemtype
+denotes the element type of
+.metn type ,
+which must be a pointer, array or enum.
+
+Note: there is also a macro
+.codn elemtype .
+The macro expression
+.code "(elemtype X)"
+is equivalent to the expression
+.codn "(ffi (elemtype X))" .
+
.coNP FFI types @, blkcnt-t @, blksize-t @, clockid-t @, dev-t @, fsblkcnt-t @, fsfilcnt-t @, gid-t @, id-t @, ino-t @, key-t @, loff-t @, mode-t @, nlink-t @, off-t @, pid-t @ ssize-t and @ uid-t
The additional names of various common POSIX types may also be available,
depending on platform. They are provided as
@@ -64352,10 +64370,18 @@ The macro
.code elemtype
produce the element type of an array type, or
the target type of a pointer type indicated by
-.metn type-syntax ,
-using the
-.code ffi-elemsize
-function.
+.metn type-syntax .
+Note: the
+.code elemtype
+macro may be understood in terms of several possible implementations.
+The form
+.code "(elemtype X)"
+is equivalent to
+.codn "(ffi-elemtype (ffi-type-compile X))" .
+Since there exists an
+.code elemtype
+type operator, the expression is also equivalent to
+.codn "(ffi-type-compile '(elemtype X))" .
.coNP Macro @ ffi
.synb