diff options
author | Kaz Kylheku <kaz@kylheku.com> | 2019-07-26 07:46:50 -0700 |
---|---|---|
committer | Kaz Kylheku <kaz@kylheku.com> | 2019-07-26 07:46:50 -0700 |
commit | 517d3674bc06b2c7f7b7a5cdedd0d5d995ca8f86 (patch) | |
tree | 93eee7b4459431f1e950e27548f7576575d65ccc | |
parent | 3600dc3307b5e9cf0ed49282d7eaa1867026627a (diff) | |
download | txr-517d3674bc06b2c7f7b7a5cdedd0d5d995ca8f86.tar.gz txr-517d3674bc06b2c7f7b7a5cdedd0d5d995ca8f86.tar.bz2 txr-517d3674bc06b2c7f7b7a5cdedd0d5d995ca8f86.zip |
FFI: elemtype as type operator, not just macro.
* ffi.c (elemtype_s): New symbol variable.
(ffi_type_compile): Handle elemtype.
(ffi_init): Initialize elemtype_s.
* txr.1: Document elemtype.
-rw-r--r-- | ffi.c | 19 | ||||
-rw-r--r-- | txr.1 | 34 |
2 files changed, 48 insertions, 5 deletions
@@ -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); @@ -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 |