summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorKaz Kylheku <kaz@kylheku.com>2017-05-09 06:32:50 -0700
committerKaz Kylheku <kaz@kylheku.com>2017-05-09 06:32:50 -0700
commitcb402a0d51e4fe663641ab7e99c0c9d14822c325 (patch)
tree3ae88c730f523cd8838a9833d4b2bd87e48f466a
parent8beec7d8a7f71ce83fd5ac14ec15df46207e9223 (diff)
downloadtxr-cb402a0d51e4fe663641ab7e99c0c9d14822c325.tar.gz
txr-cb402a0d51e4fe663641ab7e99c0c9d14822c325.tar.bz2
txr-cb402a0d51e4fe663641ab7e99c0c9d14822c325.zip
ffi: integers and chars may convert to C float.
* ffi.c (ffi_float_put, ffi_double_put): Support a useful type looseness by allowing integers and character Lisp values to pair with FFI floating-point types, imitating the conversion which happens in C function calls. * txr.1: Updated.
-rw-r--r--ffi.c34
-rw-r--r--txr.16
2 files changed, 33 insertions, 7 deletions
diff --git a/ffi.c b/ffi.c
index f45242b0..cdfe41ca 100644
--- a/ffi.c
+++ b/ffi.c
@@ -481,11 +481,23 @@ static val ffi_ulong_get(struct txr_ffi_type *tft, mem_t *src, val self)
static void ffi_float_put(struct txr_ffi_type *tft, val n, mem_t *dst, val self)
{
- double f = c_flo(n);
double v;
- if (f > FLT_MAX || f < FLT_MIN)
+
+ switch (type(n)) {
+ case NUM:
+ case CHR:
+ v = c_num(n);
+ break;
+ case BGNUM:
+ n = int_flo(n);
+ /* fallthrough */
+ default:
+ v = c_flo(n);
+ break;
+ }
+
+ if (v > FLT_MAX || v < FLT_MIN)
uw_throwf(error_s, lit("~a: ~s is out of float range"), self, num, nao);
- v = f;
*coerce(float *, dst) = v;
}
@@ -498,7 +510,21 @@ static val ffi_float_get(struct txr_ffi_type *tft, mem_t *src, val self)
static void ffi_double_put(struct txr_ffi_type *tft, val n, mem_t *dst,
val self)
{
- double v = c_flo(n);
+ double v;
+
+ switch (type(n)) {
+ case NUM:
+ case CHR:
+ v = c_num(n);
+ break;
+ case BGNUM:
+ n = int_flo(n);
+ /* fallthrough */
+ default:
+ v = c_flo(n);
+ break;
+ }
+
*coerce(double *, dst) = v;
}
diff --git a/txr.1 b/txr.1
index 2784fc54..e3ca900f 100644
--- a/txr.1
+++ b/txr.1
@@ -52882,9 +52882,9 @@ They convert like integer types: both Lisp integers and characters
convert to these types, if in a suitable range; and under
the reverse conversion, the foreign values become Lisp integers.
.ccIP @ float and @ double
-These types correspond to the same-named C types. Only the \*(TL type
-.code float
-converts to these types. Because the \*(TL
+These types correspond to the same-named C types. They convert
+Lisp integers, characters and floating-point numbers to these C types.
+Because the \*(TL
.code float
is represented as a C
.code double