summaryrefslogtreecommitdiff
path: root/libguile/numbers.c
diff options
context:
space:
mode:
authorAndy Wingo <wingo@pobox.com>2022-01-06 21:04:23 +0100
committerAndy Wingo <wingo@pobox.com>2022-01-13 09:37:17 +0100
commit717e787da6ae75bbaa53139c0ef3791cd758a9d8 (patch)
tree8d00b014c26883916b4e62d75d6f1a06ff7bc6be /libguile/numbers.c
parent27910181c53a7f836bfc8dc9c5619e2e3110eeaf (diff)
downloadguile-717e787da6ae75bbaa53139c0ef3791cd758a9d8.tar.gz
Reimplement scm_{to,from}_{int32,uint32}
* libguile/numbers.c (scm_to_int32, scm_from_int32, scm_to_uint32): (scm_from_uint32): Reimplement inline. * libguile/integers.c (make_bignum_2): (make_bignum_from_uint64): (negative_uint32_to_int32): (positive_uint32_to_int32): (bignum_to_int32): (bignum_to_uint32): (scm_integer_from_int32): (scm_integer_from_uint32): (scm_integer_to_int32_z): (scm_integer_to_uint32_z): Better int32 support for 32-bit machines.
Diffstat (limited to 'libguile/numbers.c')
-rw-r--r--libguile/numbers.c81
1 files changed, 67 insertions, 14 deletions
diff --git a/libguile/numbers.c b/libguile/numbers.c
index b1ef37752..22321ebb2 100644
--- a/libguile/numbers.c
+++ b/libguile/numbers.c
@@ -6958,21 +6958,74 @@ scm_from_uint16 (uint16_t arg)
return SCM_I_MAKINUM (arg);
}
-#define TYPE int32_t
-#define TYPE_MIN INT32_MIN
-#define TYPE_MAX INT32_MAX
-#define SIZEOF_TYPE 4
-#define SCM_TO_TYPE_PROTO(arg) scm_to_int32 (arg)
-#define SCM_FROM_TYPE_PROTO(arg) scm_from_int32 (arg)
-#include "conv-integer.i.c"
+int32_t
+scm_to_int32 (SCM arg)
+{
+#if SCM_SIZEOF_LONG == 4
+ if (SCM_I_INUMP (arg))
+ return SCM_I_INUM (arg);
+ else if (!SCM_BIGP (arg))
+ scm_wrong_type_arg_msg (NULL, 0, arg, "exact integer");
+ int32_t ret;
+ if (scm_integer_to_int32_z (scm_bignum (arg), &ret))
+ return ret;
+ range_error (arg, scm_integer_from_int32 (INT32_MIN),
+ scm_integer_from_int32 (INT32_MAX));
+#elif SCM_SIZEOF_LONG == 8
+ return inum_in_range (arg, INT32_MIN, INT32_MAX);
+#else
+#error bad inum size
+#endif
+}
-#define TYPE uint32_t
-#define TYPE_MIN 0
-#define TYPE_MAX UINT32_MAX
-#define SIZEOF_TYPE 4
-#define SCM_TO_TYPE_PROTO(arg) scm_to_uint32 (arg)
-#define SCM_FROM_TYPE_PROTO(arg) scm_from_uint32 (arg)
-#include "conv-uinteger.i.c"
+SCM
+scm_from_int32 (int32_t arg)
+{
+#if SCM_SIZEOF_LONG == 4
+ return scm_integer_from_int32 (arg);
+#elif SCM_SIZEOF_LONG == 8
+ return SCM_I_MAKINUM (arg);
+#else
+#error bad inum size
+#endif
+}
+
+uint32_t
+scm_to_uint32 (SCM arg)
+{
+#if SCM_SIZEOF_LONG == 4
+ if (SCM_I_INUMP (arg))
+ {
+ if (SCM_I_INUM (arg) > 0)
+ return SCM_I_INUM (arg);
+ }
+ else if (SCM_BIGP (arg))
+ {
+ uint32_t ret;
+ if (scm_integer_to_uint32_z (scm_bignum (arg), &ret))
+ return ret;
+ }
+ else
+ scm_wrong_type_arg_msg (NULL, 0, arg, "exact integer");
+ range_error (arg, 0, scm_integer_from_uint32 (UINT32_MAX));
+#elif SCM_SIZEOF_LONG == 8
+ return inum_in_range (arg, 0, UINT32_MAX);
+#else
+#error bad inum size
+#endif
+}
+
+SCM
+scm_from_uint32 (uint32_t arg)
+{
+#if SCM_SIZEOF_LONG == 4
+ return scm_integer_from_uint32 (arg);
+#elif SCM_SIZEOF_LONG == 8
+ return SCM_I_MAKINUM (arg);
+#else
+#error bad inum size
+#endif
+}
#define TYPE scm_t_wchar
#define TYPE_MIN (int32_t)-1