wingo pushed a commit to branch wip-whippet
in repository guile.

commit 9fd851da658c9eb0a5fee6d033ce4c597ae1418d
Author: Andy Wingo <wi...@pobox.com>
AuthorDate: Fri Jun 20 16:41:47 2025 +0200

    Get fractions off scm_double_cell
    
    * libguile/numbers.h (scm_t_double, scm_t_complex): Change type and pad
    to scm_t_bits.
    (struct scm_fraction): New type.
    (scm_is_fraction, scm_to_fraction, scm_from_fraction)
    (scm_fraction_numerator, scm_fraction_denominator): New helpers.
    (SCM_FRACTIONP, SCM_FRACTION_NUMERATOR, SCM_FRACTION_DENOMINATOR): Use
    new helpers.
    * libguile/numbers.c (scm_i_make_ratio_already_reduced): Allocate using
    scm_allocate_tagged.
---
 libguile/numbers.c | 10 +++++----
 libguile/numbers.h | 59 +++++++++++++++++++++++++++++++++++++++++++++---------
 2 files changed, 56 insertions(+), 13 deletions(-)

diff --git a/libguile/numbers.c b/libguile/numbers.c
index 1d9a86f78..2bb5c99d0 100644
--- a/libguile/numbers.c
+++ b/libguile/numbers.c
@@ -234,9 +234,12 @@ scm_i_make_ratio_already_reduced (SCM numerator, SCM 
denominator)
   if (scm_is_eq (denominator, SCM_INUM1))
     return numerator;
 
-  return scm_double_cell (scm_tc16_fraction,
-                         SCM_UNPACK (numerator),
-                         SCM_UNPACK (denominator), 0);
+  struct scm_fraction *f = scm_allocate_tagged (SCM_I_CURRENT_THREAD,
+                                                sizeof (*f));
+  f->tag = scm_tc16_fraction;
+  f->numerator = numerator;
+  f->denominator = denominator;
+  return scm_from_fraction (f);
 }
 
 static SCM scm_exact_integer_quotient (SCM x, SCM y);
@@ -3571,7 +3574,6 @@ scm_i_print_double (double val, SCM port)
 
 int
 scm_print_complex (SCM sexp, SCM port, scm_print_state *pstate SCM_UNUSED)
-
 {
   char num_buf[FLOBUFLEN];
   scm_lfwrite (num_buf, iflo2str (sexp, num_buf, 10), port);
diff --git a/libguile/numbers.h b/libguile/numbers.h
index 84ad5466f..2561be825 100644
--- a/libguile/numbers.h
+++ b/libguile/numbers.h
@@ -1,7 +1,7 @@
 #ifndef SCM_NUMBERS_H
 #define SCM_NUMBERS_H
 
-/* Copyright 1995-1996,1998,2000-2006,2008-2011,2013-2014,2016-2018,2021-2022
+/* Copyright 
1995-1996,1998,2000-2006,2008-2011,2013-2014,2016-2018,2021-2022,2025
      Free Software Foundation, Inc.
 
    This file is part of Guile.
@@ -171,31 +171,72 @@ typedef long scm_t_inum;
 #define SCM_NUMBERP(x) (SCM_I_INUMP(x) || SCM_NUMP(x))
 #define SCM_NUMP(x) (SCM_HAS_TYP7 (x, scm_tc7_number))
 
-#define SCM_FRACTIONP(x) (SCM_HAS_TYP16 (x, scm_tc16_fraction))
-#define SCM_FRACTION_NUMERATOR(x) (SCM_CELL_OBJECT_1 (x))
-#define SCM_FRACTION_DENOMINATOR(x) (SCM_CELL_OBJECT_2 (x))
-
 
 
 typedef struct scm_t_double
 {
-  SCM type;
+  scm_t_bits type;
 #if SCM_SIZEOF_UINTPTR_T != 8
-  SCM pad;
+  scm_t_bits pad;
 #endif
   double real;
 } scm_t_double;
 
 typedef struct scm_t_complex
 {
-  SCM type;
+  scm_t_bits type;
 #if SCM_SIZEOF_UINTPTR_T != 8
-  SCM pad;
+  scm_t_bits pad;
 #endif
   double real;
   double imag;
 } scm_t_complex;
 
+struct scm_fraction
+{
+  scm_t_bits tag;
+  SCM numerator;
+  SCM denominator;
+};
+
+
+
+static inline int
+scm_is_fraction (SCM x)
+{
+  return SCM_HAS_TYP16 (x, scm_tc16_fraction);
+}
+
+static inline struct scm_fraction *
+scm_to_fraction (SCM x)
+{
+  if (!scm_is_fraction (x))
+    abort ();
+  return (struct scm_fraction *) SCM_UNPACK_POINTER (x);
+}
+
+static inline SCM
+scm_from_fraction (struct scm_fraction *f)
+{
+  return SCM_PACK_POINTER (f);
+}
+
+static inline SCM
+scm_fraction_numerator (struct scm_fraction *f)
+{
+  return f->numerator;
+}
+
+static inline SCM
+scm_fraction_denominator (struct scm_fraction *f)
+{
+  return f->denominator;
+}
+
+#define SCM_FRACTIONP(x) (scm_is_fraction (x))
+#define SCM_FRACTION_NUMERATOR(x) (scm_fraction_numerator (scm_to_fraction 
(x)))
+#define SCM_FRACTION_DENOMINATOR(x) (scm_fraction_denominator (scm_to_fraction 
(x)))
+
 
 
 SCM_API SCM scm_exact_p (SCM x);

Reply via email to