diff options
author | Kaz Kylheku <kaz@kylheku.com> | 2019-07-26 07:12:50 -0700 |
---|---|---|
committer | Kaz Kylheku <kaz@kylheku.com> | 2019-07-26 07:12:50 -0700 |
commit | 55c2dbb134edce8835cf94c2425b80db256bccf2 (patch) | |
tree | d0e506c324e0e2c4f907da61c4e5f7f2740b0ddc /ffi.c | |
parent | 6560fc0563a891294a808e880f201663365af1bd (diff) | |
download | txr-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.c | 26 |
1 files changed, 26 insertions, 0 deletions
@@ -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"), |