summaryrefslogtreecommitdiffstats
path: root/ffi.c
diff options
context:
space:
mode:
authorKaz Kylheku <kaz@kylheku.com>2019-07-26 07:12:50 -0700
committerKaz Kylheku <kaz@kylheku.com>2019-07-26 07:12:50 -0700
commit55c2dbb134edce8835cf94c2425b80db256bccf2 (patch)
treed0e506c324e0e2c4f907da61c4e5f7f2740b0ddc /ffi.c
parent6560fc0563a891294a808e880f201663365af1bd (diff)
downloadtxr-55c2dbb134edce8835cf94c2425b80db256bccf2.tar.gz
txr-55c2dbb134edce8835cf94c2425b80db256bccf2.tar.bz2
txr-55c2dbb134edce8835cf94c2425b80db256bccf2.zip
FFI: allow member type reference using referencing dot.
* ffi.c (ffi_type_compile): New case handling qref_s symbol. * txr.1: Documented.
Diffstat (limited to 'ffi.c')
-rw-r--r--ffi.c26
1 files changed, 26 insertions, 0 deletions
diff --git a/ffi.c b/ffi.c
index 64616b71..47ca544b 100644
--- a/ffi.c
+++ b/ffi.c
@@ -3542,6 +3542,32 @@ val ffi_type_compile(val syntax)
tft->rput = ffi_bool_rput;
#endif
return type_copy;
+ } else if (sym == qref_s) {
+ val args = cdr(syntax);
+ val type = nil;
+ struct txr_ffi_type *tft = 0;
+
+ for (; consp(args); args = cdr(args)) {
+ val next = car(args);
+ if (!tft) {
+ type = ffi_type_compile(next);
+ tft = ffi_type_struct(type);
+ if (tft->clone != ffi_struct_clone)
+ uw_throwf(error_s, lit("~a: ~s in ~s isn't a struct/union type"),
+ self, next, syntax, nao);
+ } else {
+ tft = ffi_find_memb(tft, next);
+ if (!tft)
+ uw_throwf(error_s, lit("~a: ~s in ~s is a nonexistent member"),
+ self, next, syntax, nao);
+ type = tft->self;
+ }
+ }
+
+ if (type == nil || args)
+ uw_throwf(error_s, lit("~a: invalid ~s syntax"), self, sym, nao);
+
+ return type;
}
uw_throwf(error_s, lit("~a: unrecognized type operator: ~s"),