From cb402a0d51e4fe663641ab7e99c0c9d14822c325 Mon Sep 17 00:00:00 2001 From: Kaz Kylheku Date: Tue, 9 May 2017 06:32:50 -0700 Subject: 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. --- ffi.c | 34 ++++++++++++++++++++++++++++++---- txr.1 | 6 +++--- 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 -- cgit v1.2.3