summaryrefslogtreecommitdiff
path: root/libguile/integers.c
diff options
context:
space:
mode:
authorAndy Wingo <wingo@pobox.com>2022-01-06 20:12:06 +0100
committerAndy Wingo <wingo@pobox.com>2022-01-13 09:37:16 +0100
commit27910181c53a7f836bfc8dc9c5619e2e3110eeaf (patch)
tree056872d3cb0460ca3cb627355814e2debf7df6b2 /libguile/integers.c
parentf4db3ca3f9986477f6a8d4eddae8b88604e3f8a9 (diff)
downloadguile-27910181c53a7f836bfc8dc9c5619e2e3110eeaf.tar.gz
Reimplement scm_from_int8 etc
* libguile/integers.c (make_bignum_from_uint64): (make_bignum_from_int64): New helpers. (scm_integer_from_int64): (scm_integer_from_uint64): New internal functions. * libguile/integers.h: Declare new internal functions. * libguile/numbers.c (range_error): Declare as noreturn.xo (inum_in_range): New helper. (scm_from_signed_integer): (scm_to_signed_integer): (scm_from_unsigned_integer): (scm_to_unsigned_integer): (scm_to_int8): (scm_from_int8): (scm_to_uint8): (scm_from_uint8): (scm_to_int16): (scm_from_int16): (scm_to_uint16): (scm_from_uint16): Implement manually.
Diffstat (limited to 'libguile/integers.c')
-rw-r--r--libguile/integers.c41
1 files changed, 41 insertions, 0 deletions
diff --git a/libguile/integers.c b/libguile/integers.c
index b8cb1a908..9ec42694f 100644
--- a/libguile/integers.c
+++ b/libguile/integers.c
@@ -183,6 +183,31 @@ make_bignum_1 (int is_negative, mp_limb_t limb)
}
static struct scm_bignum *
+make_bignum_from_uint64 (uint64_t val)
+{
+#if SCM_SIZEOF_LONG == 4
+ mp_limb_t lo = val, hi = val >> 32;
+ struct scm_bignum *z = allocate_bignum (hi ? 2 : 1);
+ z->limbs[0] = lo;
+ if (hi)
+ z->limbs[1] = hi;
+ return z;
+#else
+ struct scm_bignum *z = allocate_bignum (1);
+ z->limbs[0] = val;
+ return z;
+#endif
+}
+
+static struct scm_bignum *
+make_bignum_from_int64 (int64_t val)
+{
+ return val < 0
+ ? negate_bignum (make_bignum_from_uint64 (int64_magnitude (val)))
+ : make_bignum_from_uint64 (val);
+}
+
+static struct scm_bignum *
ulong_to_bignum (unsigned long u)
{
return make_bignum_1 (0, u);
@@ -2896,6 +2921,22 @@ scm_integer_exact_quotient_zz (struct scm_bignum *n, struct scm_bignum *d)
return take_mpz (q);
}
+SCM
+scm_integer_from_int64 (int64_t n)
+{
+ if (SCM_FIXABLE (n))
+ return SCM_I_MAKINUM (n);
+ return scm_from_bignum (make_bignum_from_int64 (n));
+}
+
+SCM
+scm_integer_from_uint64 (uint64_t n)
+{
+ if (SCM_POSFIXABLE (n))
+ return SCM_I_MAKINUM (n);
+ return scm_from_bignum (make_bignum_from_uint64 (n));
+}
+
int
scm_integer_to_int64_z (struct scm_bignum *z, int64_t *val)
{