Ticket #1773: numeric-type-hash-switches-dyadic-procs.patch

File numeric-type-hash-switches-dyadic-procs.patch, 32.9 KB (added by sjamaan, 3 years ago)

Incremental diff to add hashing for two argument types simultaneously

  • runtime.c

    diff --git a/runtime.c b/runtime.c
    index cf7351e7..56e91c9e 100644
    a b static C_TLS int timezone; 
    269269#define C_thread_id(x)   C_block_item((x), 14)
    270270
    271271
     272#ifdef C_SIXTY_FOUR
     273# define C_TYPE_HASH_SHIFT           48
     274#else
     275# define C_TYPE_HASH_SHIFT           16
     276#endif
     277
    272278/* A numeric type hash packs the type bits into the bottom 12 bits (regardless of immediate/block type). */
    273279/* NOTE: Only fixnum-immediates are currently distinguished - to make this more generic one would need to use one more test */
    274 #define C_type_hash(x)               (((x) & C_IMMEDIATE_MARK_BITS) ? ((x) & C_FIXNUM_BIT) : C_header_bits(x))
     280#define C_type_hash(x)               (((x) & C_IMMEDIATE_MARK_BITS) ? ((x) & C_FIXNUM_BIT) : (C_header_bits(x) >> C_TYPE_HASH_SHIFT))
     281/* For dyadic procedures (with two arguments), combine both type hashes */
     282#define C_dyadic_hash(x, y)          ((x << 16) | y)
    275283
    276284/* We only care about numeric type hashes currently */
    277285#define C_FIXNUM_TYPE_HASH           C_FIXNUM_BIT
    278 #define C_FLONUM_TYPE_HASH           C_FLONUM_TYPE
    279 #define C_BIGNUM_TYPE_HASH           C_BIGNUM_TYPE
    280 #define C_RATNUM_TYPE_HASH           C_RATNUM_TYPE
    281 #define C_CPLXNUM_TYPE_HASH          C_CPLXNUM_TYPE
     286#define C_FLONUM_TYPE_HASH           (C_FLONUM_TYPE >> C_TYPE_HASH_SHIFT)
     287#define C_BIGNUM_TYPE_HASH           (C_BIGNUM_TYPE >> C_TYPE_HASH_SHIFT)
     288#define C_RATNUM_TYPE_HASH           (C_RATNUM_TYPE >> C_TYPE_HASH_SHIFT)
     289#define C_CPLXNUM_TYPE_HASH          (C_CPLXNUM_TYPE >> C_TYPE_HASH_SHIFT)
    282290
    283291
    284292/* Type definitions: */
    cplx_times(C_word **ptr, C_word rx, C_word ix, C_word ry, C_word iy) 
    80358043C_regparm C_word C_fcall
    80368044C_s_a_i_times(C_word **ptr, C_word n, C_word x, C_word y)
    80378045{
    8038   switch(C_type_hash(x)) { /* TODO: Use dyadic_hash? */
    8039   case C_FIXNUM_TYPE_HASH:
    8040     switch(C_type_hash(y)) {
    8041     case C_FIXNUM_TYPE_HASH:
    8042       return C_a_i_fixnum_times(ptr, 2, x, y);
     8046  switch(C_dyadic_hash(C_type_hash(x), C_type_hash(y))) {
     8047  case C_dyadic_hash(C_FIXNUM_TYPE_HASH, C_FIXNUM_TYPE_HASH):
     8048    return C_a_i_fixnum_times(ptr, 2, x, y);
    80438049
    8044     case C_FLONUM_TYPE_HASH:
    8045       return C_flonum(ptr, (double)C_unfix(x) * C_flonum_magnitude(y));
     8050  case C_dyadic_hash(C_FIXNUM_TYPE_HASH, C_FLONUM_TYPE_HASH):
     8051    return C_flonum(ptr, (double)C_unfix(x) * C_flonum_magnitude(y));
    80468052
    8047     case C_BIGNUM_TYPE_HASH:
    8048       return C_s_a_u_i_integer_times(ptr, 2, x, y);
     8053  case C_dyadic_hash(C_FIXNUM_TYPE_HASH, C_BIGNUM_TYPE_HASH):
     8054    return C_s_a_u_i_integer_times(ptr, 2, x, y);
    80498055
    8050     case C_RATNUM_TYPE_HASH:
    8051       return rat_times_integer(ptr, y, x);
     8056  case C_dyadic_hash(C_FIXNUM_TYPE_HASH, C_RATNUM_TYPE_HASH):
     8057    return rat_times_integer(ptr, y, x);
    80528058
    8053     case C_CPLXNUM_TYPE_HASH:
    8054       return cplx_times(ptr, x, C_fix(0),
    8055                         C_u_i_cplxnum_real(y), C_u_i_cplxnum_imag(y));
     8059  case C_dyadic_hash(C_FIXNUM_TYPE_HASH, C_CPLXNUM_TYPE_HASH):
     8060    return cplx_times(ptr, x, C_fix(0),
     8061                      C_u_i_cplxnum_real(y), C_u_i_cplxnum_imag(y));
    80568062
    8057     default:
    8058       barf(C_BAD_ARGUMENT_TYPE_NO_NUMBER_ERROR, "*", y);
    8059     }
    80608063
    8061     case C_FLONUM_TYPE_HASH:
    8062       switch(C_type_hash(y)) {
    8063       case C_FIXNUM_TYPE_HASH:
    8064         return C_flonum(ptr, C_flonum_magnitude(x) * (double)C_unfix(y));
     8064  case C_dyadic_hash(C_FLONUM_TYPE_HASH, C_FIXNUM_TYPE_HASH):
     8065    return C_flonum(ptr, C_flonum_magnitude(x) * (double)C_unfix(y));
    80658066
    8066       case C_FLONUM_TYPE_HASH:
    8067         return C_a_i_flonum_times(ptr, 2, x, y);
     8067  case C_dyadic_hash(C_FLONUM_TYPE_HASH, C_FLONUM_TYPE_HASH):
     8068    return C_a_i_flonum_times(ptr, 2, x, y);
    80688069
    8069       case C_BIGNUM_TYPE_HASH:
    8070         return C_flonum(ptr, C_flonum_magnitude(x) * C_bignum_to_double(y));
     8070  case C_dyadic_hash(C_FLONUM_TYPE_HASH, C_BIGNUM_TYPE_HASH):
     8071    return C_flonum(ptr, C_flonum_magnitude(x) * C_bignum_to_double(y));
    80718072
    8072       case C_RATNUM_TYPE_HASH:
    8073         return C_s_a_i_times(ptr, 2, x, C_a_i_exact_to_inexact(ptr, 1, y));
    8074 
    8075       case C_CPLXNUM_TYPE_HASH:
    8076       {
    8077         C_word ab[C_SIZEOF_FLONUM], *a = ab;
    8078         return cplx_times(ptr, x, C_flonum(&a, 0.0),
    8079                           C_u_i_cplxnum_real(y), C_u_i_cplxnum_imag(y));
    8080       }
     8073  case C_dyadic_hash(C_FLONUM_TYPE_HASH, C_RATNUM_TYPE_HASH):
     8074    return C_s_a_i_times(ptr, 2, x, C_a_i_exact_to_inexact(ptr, 1, y));
    80818075
    8082       default:
    8083         barf(C_BAD_ARGUMENT_TYPE_NO_NUMBER_ERROR, "*", y);
    8084       }
     8076  case C_dyadic_hash(C_FLONUM_TYPE_HASH, C_CPLXNUM_TYPE_HASH):
     8077  {
     8078    C_word ab[C_SIZEOF_FLONUM], *a = ab;
     8079    return cplx_times(ptr, x, C_flonum(&a, 0.0),
     8080                      C_u_i_cplxnum_real(y), C_u_i_cplxnum_imag(y));
     8081  }
    80858082
    8086     case C_BIGNUM_TYPE_HASH:
    8087       switch(C_type_hash(y)) {
    8088       case C_FIXNUM_TYPE_HASH:
    8089         return C_s_a_u_i_integer_times(ptr, 2, x, y);
     8083  case C_dyadic_hash(C_BIGNUM_TYPE_HASH, C_FIXNUM_TYPE_HASH):
     8084    return C_s_a_u_i_integer_times(ptr, 2, x, y);
    80908085
    8091       case C_FLONUM_TYPE_HASH:
    8092         return C_flonum(ptr, C_bignum_to_double(x) * C_flonum_magnitude(y));
     8086  case C_dyadic_hash(C_BIGNUM_TYPE_HASH, C_FLONUM_TYPE_HASH):
     8087    return C_flonum(ptr, C_bignum_to_double(x) * C_flonum_magnitude(y));
    80938088
    8094       case C_BIGNUM_TYPE_HASH:
    8095         return C_s_a_u_i_integer_times(ptr, 2, x, y);
     8089  case C_dyadic_hash(C_BIGNUM_TYPE_HASH, C_BIGNUM_TYPE_HASH):
     8090    return C_s_a_u_i_integer_times(ptr, 2, x, y);
    80968091
    8097       case C_RATNUM_TYPE_HASH:
    8098         return rat_times_integer(ptr, y, x);
     8092  case C_dyadic_hash(C_BIGNUM_TYPE_HASH, C_RATNUM_TYPE_HASH):
     8093    return rat_times_integer(ptr, y, x);
    80998094
    8100       case C_CPLXNUM_TYPE_HASH:
    8101         return cplx_times(ptr, x, C_fix(0),
    8102                           C_u_i_cplxnum_real(y), C_u_i_cplxnum_imag(y));
     8095  case C_dyadic_hash(C_BIGNUM_TYPE_HASH, C_CPLXNUM_TYPE_HASH):
     8096    return cplx_times(ptr, x, C_fix(0),
     8097                      C_u_i_cplxnum_real(y), C_u_i_cplxnum_imag(y));
    81038098
    8104       default:
    8105         barf(C_BAD_ARGUMENT_TYPE_NO_NUMBER_ERROR, "*", y);
    8106       }
    81078099
    8108     case C_RATNUM_TYPE_HASH:
    8109       switch(C_type_hash(y)) {
    8110       case C_FIXNUM_TYPE_HASH:
    8111         return rat_times_integer(ptr, x, y);
     8100  case C_dyadic_hash(C_RATNUM_TYPE_HASH, C_FIXNUM_TYPE_HASH):
     8101    return rat_times_integer(ptr, x, y);
    81128102
    8113       case C_FLONUM_TYPE_HASH:
    8114         return C_s_a_i_times(ptr, 2, C_a_i_exact_to_inexact(ptr, 1, x), y);
     8103  case C_dyadic_hash(C_RATNUM_TYPE_HASH, C_FLONUM_TYPE_HASH):
     8104    return C_s_a_i_times(ptr, 2, C_a_i_exact_to_inexact(ptr, 1, x), y);
    81158105
    8116       case C_BIGNUM_TYPE_HASH:
    8117         return rat_times_integer(ptr, x, y);
     8106  case C_dyadic_hash(C_RATNUM_TYPE_HASH, C_BIGNUM_TYPE_HASH):
     8107    return rat_times_integer(ptr, x, y);
    81188108
    8119       case C_RATNUM_TYPE_HASH:
    8120         return rat_times_rat(ptr, x, y);
     8109  case C_dyadic_hash(C_RATNUM_TYPE_HASH, C_RATNUM_TYPE_HASH):
     8110    return rat_times_rat(ptr, x, y);
    81218111
    8122       case C_CPLXNUM_TYPE_HASH:
    8123         return cplx_times(ptr, x, C_fix(0),
    8124                           C_u_i_cplxnum_real(y), C_u_i_cplxnum_imag(y));
     8112  case C_dyadic_hash(C_RATNUM_TYPE_HASH, C_CPLXNUM_TYPE_HASH):
     8113    return cplx_times(ptr, x, C_fix(0),
     8114                      C_u_i_cplxnum_real(y), C_u_i_cplxnum_imag(y));
    81258115
    8126       default:
    8127         barf(C_BAD_ARGUMENT_TYPE_NO_NUMBER_ERROR, "*", y);
    8128       }
     8116  case C_dyadic_hash(C_CPLXNUM_TYPE_HASH, C_CPLXNUM_TYPE_HASH):
     8117    return cplx_times(ptr, C_u_i_cplxnum_real(x), C_u_i_cplxnum_imag(x),
     8118                      C_u_i_cplxnum_real(y), C_u_i_cplxnum_imag(y));
    81298119
    8130     case C_CPLXNUM_TYPE_HASH:
    8131       if (!C_immediatep(y) && C_block_header(y) == C_CPLXNUM_TAG) {
    8132         return cplx_times(ptr, C_u_i_cplxnum_real(x), C_u_i_cplxnum_imag(x),
    8133                           C_u_i_cplxnum_real(y), C_u_i_cplxnum_imag(y));
    8134       } else {
    8135         C_word ab[C_SIZEOF_FLONUM], *a = ab, yi;
    8136         yi = C_truep(C_i_flonump(y)) ? C_flonum(&a,0) : C_fix(0);
    8137         return cplx_times(ptr, C_u_i_ratnum_num(x), C_u_i_ratnum_denom(x), y, yi);
    8138       }
     8120  case C_dyadic_hash(C_CPLXNUM_TYPE_HASH, C_FIXNUM_TYPE_HASH):
     8121  case C_dyadic_hash(C_CPLXNUM_TYPE_HASH, C_FLONUM_TYPE_HASH):
     8122  case C_dyadic_hash(C_CPLXNUM_TYPE_HASH, C_BIGNUM_TYPE_HASH):
     8123  case C_dyadic_hash(C_CPLXNUM_TYPE_HASH, C_RATNUM_TYPE_HASH):
     8124  {
     8125    C_word ab[C_SIZEOF_FLONUM], *a = ab, yi;
     8126    yi = C_truep(C_i_flonump(y)) ? C_flonum(&a,0) : C_fix(0);
     8127    return cplx_times(ptr, C_u_i_ratnum_num(x), C_u_i_ratnum_denom(x), y, yi);
     8128  }
    81398129
    81408130  default:
    8141     barf(C_BAD_ARGUMENT_TYPE_NO_NUMBER_ERROR, "*", x);
     8131    if (!C_truep(C_i_numberp(x)))
     8132      barf(C_BAD_ARGUMENT_TYPE_NO_NUMBER_ERROR, "*", x);
     8133    else
     8134      barf(C_BAD_ARGUMENT_TYPE_NO_NUMBER_ERROR, "*", y);
    81428135  }
    81438136}
    81448137
    static C_word rat_plusmin_rat(C_word **ptr, C_word x, C_word y, integer_plusmin_ 
    84528445C_regparm C_word C_fcall
    84538446C_s_a_i_plus(C_word **ptr, C_word n, C_word x, C_word y)
    84548447{
    8455   switch(C_type_hash(x)) { /* TODO: Use dyadic_hash? */
    8456   case C_FIXNUM_TYPE_HASH:
    8457     switch(C_type_hash(y)) {
    8458     case C_FIXNUM_TYPE_HASH:
    8459       return C_a_i_fixnum_plus(ptr, 2, x, y);
     8448  switch(C_dyadic_hash(C_type_hash(x), C_type_hash(y))) {
     8449  case C_dyadic_hash(C_FIXNUM_TYPE_HASH, C_FIXNUM_TYPE_HASH):
     8450    return C_a_i_fixnum_plus(ptr, 2, x, y);
    84608451
    8461     case C_FLONUM_TYPE_HASH:
    8462       return C_flonum(ptr, (double)C_unfix(x) + C_flonum_magnitude(y));
     8452  case C_dyadic_hash(C_FIXNUM_TYPE_HASH, C_FLONUM_TYPE_HASH):
     8453    return C_flonum(ptr, (double)C_unfix(x) + C_flonum_magnitude(y));
    84638454
    8464     case C_BIGNUM_TYPE_HASH:
    8465       return C_s_a_u_i_integer_plus(ptr, 2, x, y);
     8455  case C_dyadic_hash(C_FIXNUM_TYPE_HASH, C_BIGNUM_TYPE_HASH):
     8456    return C_s_a_u_i_integer_plus(ptr, 2, x, y);
    84668457
    8467     case C_RATNUM_TYPE_HASH:
    8468       return rat_plusmin_integer(ptr, y, x, C_s_a_u_i_integer_plus);
     8458  case C_dyadic_hash(C_FIXNUM_TYPE_HASH, C_RATNUM_TYPE_HASH):
     8459    return rat_plusmin_integer(ptr, y, x, C_s_a_u_i_integer_plus);
    84698460
    8470     case C_CPLXNUM_TYPE_HASH:
    8471     {
    8472       C_word real_sum = C_s_a_i_plus(ptr, 2, x, C_u_i_cplxnum_real(y)),
    8473              imag = C_u_i_cplxnum_imag(y);
    8474       if (C_truep(C_u_i_inexactp(real_sum)))
    8475         imag = C_a_i_exact_to_inexact(ptr, 1, imag);
    8476       return C_cplxnum(ptr, real_sum, imag);
    8477     }
    8478 
    8479     default:
    8480       barf(C_BAD_ARGUMENT_TYPE_NO_NUMBER_ERROR, "+", y);
    8481     }
     8461  case C_dyadic_hash(C_FIXNUM_TYPE_HASH, C_CPLXNUM_TYPE_HASH):
     8462  {
     8463    C_word real_sum = C_s_a_i_plus(ptr, 2, x, C_u_i_cplxnum_real(y)),
     8464      imag = C_u_i_cplxnum_imag(y);
     8465    if (C_truep(C_u_i_inexactp(real_sum)))
     8466      imag = C_a_i_exact_to_inexact(ptr, 1, imag);
     8467    return C_cplxnum(ptr, real_sum, imag);
     8468  }
    84828469
    8483     case C_FLONUM_TYPE_HASH:
    8484       switch(C_type_hash(y)) {
    8485       case C_FIXNUM_TYPE_HASH:
    8486         return C_flonum(ptr, C_flonum_magnitude(x) + (double)C_unfix(y));
     8470  case C_dyadic_hash(C_FLONUM_TYPE_HASH, C_FIXNUM_TYPE_HASH):
     8471    return C_flonum(ptr, C_flonum_magnitude(x) + (double)C_unfix(y));
    84878472
    8488       case C_FLONUM_TYPE_HASH:
    8489         return C_a_i_flonum_plus(ptr, 2, x, y);
     8473  case C_dyadic_hash(C_FLONUM_TYPE_HASH, C_FLONUM_TYPE_HASH):
     8474    return C_a_i_flonum_plus(ptr, 2, x, y);
    84908475
    8491       case C_BIGNUM_TYPE_HASH:
    8492         return C_flonum(ptr, C_flonum_magnitude(x)+C_bignum_to_double(y));
     8476  case C_dyadic_hash(C_FLONUM_TYPE_HASH, C_BIGNUM_TYPE_HASH):
     8477    return C_flonum(ptr, C_flonum_magnitude(x)+C_bignum_to_double(y));
    84938478
    8494       case C_RATNUM_TYPE_HASH:
    8495         return C_s_a_i_plus(ptr, 2, x, C_a_i_exact_to_inexact(ptr, 1, y));
     8479  case C_dyadic_hash(C_FLONUM_TYPE_HASH, C_RATNUM_TYPE_HASH):
     8480    return C_s_a_i_plus(ptr, 2, x, C_a_i_exact_to_inexact(ptr, 1, y));
    84968481
    8497       case C_CPLXNUM_TYPE_HASH:
    8498       {
    8499         C_word real_sum = C_s_a_i_plus(ptr, 2, x, C_u_i_cplxnum_real(y)),
    8500           imag = C_u_i_cplxnum_imag(y);
    8501         if (C_truep(C_u_i_inexactp(real_sum)))
    8502           imag = C_a_i_exact_to_inexact(ptr, 1, imag);
    8503         return C_cplxnum(ptr, real_sum, imag);
    8504       }
     8482  case C_dyadic_hash(C_FLONUM_TYPE_HASH, C_CPLXNUM_TYPE_HASH):
     8483  {
     8484    C_word real_sum = C_s_a_i_plus(ptr, 2, x, C_u_i_cplxnum_real(y)),
     8485      imag = C_u_i_cplxnum_imag(y);
     8486    if (C_truep(C_u_i_inexactp(real_sum)))
     8487      imag = C_a_i_exact_to_inexact(ptr, 1, imag);
     8488    return C_cplxnum(ptr, real_sum, imag);
     8489  }
    85058490
    8506       default:
    8507         barf(C_BAD_ARGUMENT_TYPE_NO_NUMBER_ERROR, "+", y);
    8508     }
     8491  case C_dyadic_hash(C_BIGNUM_TYPE_HASH, C_FIXNUM_TYPE_HASH):
     8492    return C_s_a_u_i_integer_plus(ptr, 2, x, y);
    85098493
    8510   case C_BIGNUM_TYPE_HASH:
    8511     switch(C_type_hash(y)) {
    8512     case C_FIXNUM_TYPE_HASH:
    8513       return C_s_a_u_i_integer_plus(ptr, 2, x, y);
    8514     case C_FLONUM_TYPE_HASH:
    8515       return C_flonum(ptr, C_bignum_to_double(x)+C_flonum_magnitude(y));
     8494  case C_dyadic_hash(C_BIGNUM_TYPE_HASH, C_FLONUM_TYPE_HASH):
     8495    return C_flonum(ptr, C_bignum_to_double(x)+C_flonum_magnitude(y));
    85168496
    8517     case C_BIGNUM_TYPE_HASH:
    8518       return C_s_a_u_i_integer_plus(ptr, 2, x, y);
     8497  case C_dyadic_hash(C_BIGNUM_TYPE_HASH, C_BIGNUM_TYPE_HASH):
     8498    return C_s_a_u_i_integer_plus(ptr, 2, x, y);
    85198499
    8520     case C_RATNUM_TYPE_HASH:
    8521       return rat_plusmin_integer(ptr, y, x, C_s_a_u_i_integer_plus);
     8500  case C_dyadic_hash(C_BIGNUM_TYPE_HASH, C_RATNUM_TYPE_HASH):
     8501    return rat_plusmin_integer(ptr, y, x, C_s_a_u_i_integer_plus);
    85228502
    8523     case C_CPLXNUM_TYPE_HASH:
    8524     {
    8525       C_word real_sum = C_s_a_i_plus(ptr, 2, x, C_u_i_cplxnum_real(y)),
    8526         imag = C_u_i_cplxnum_imag(y);
    8527       if (C_truep(C_u_i_inexactp(real_sum)))
    8528         imag = C_a_i_exact_to_inexact(ptr, 1, imag);
    8529       return C_cplxnum(ptr, real_sum, imag);
    8530     }
     8503  case C_dyadic_hash(C_BIGNUM_TYPE_HASH, C_CPLXNUM_TYPE_HASH):
     8504  {
     8505    C_word real_sum = C_s_a_i_plus(ptr, 2, x, C_u_i_cplxnum_real(y)),
     8506      imag = C_u_i_cplxnum_imag(y);
     8507    if (C_truep(C_u_i_inexactp(real_sum)))
     8508      imag = C_a_i_exact_to_inexact(ptr, 1, imag);
     8509    return C_cplxnum(ptr, real_sum, imag);
     8510  }
    85318511     
    8532     default:
    8533       barf(C_BAD_ARGUMENT_TYPE_NO_NUMBER_ERROR, "+", y);
    8534     }
    8535 
    8536   case C_RATNUM_TYPE_HASH:
    8537     switch(C_type_hash(y)) {
    8538     case C_FIXNUM_TYPE_HASH:
    8539     case C_BIGNUM_TYPE_HASH:
    8540       return rat_plusmin_integer(ptr, x, y, C_s_a_u_i_integer_plus);
    8541 
    8542     case C_FLONUM_TYPE_HASH:
    8543       return C_s_a_i_plus(ptr, 2, C_a_i_exact_to_inexact(ptr, 1, x), y);
     8512  case C_dyadic_hash(C_RATNUM_TYPE_HASH, C_FIXNUM_TYPE_HASH):
     8513  case C_dyadic_hash(C_RATNUM_TYPE_HASH, C_BIGNUM_TYPE_HASH):
     8514    return rat_plusmin_integer(ptr, x, y, C_s_a_u_i_integer_plus);
    85448515
    8545     case C_RATNUM_TYPE_HASH:
    8546       return rat_plusmin_rat(ptr, x, y, C_s_a_u_i_integer_plus);
     8516  case C_dyadic_hash(C_RATNUM_TYPE_HASH, C_FLONUM_TYPE_HASH):
     8517    return C_s_a_i_plus(ptr, 2, C_a_i_exact_to_inexact(ptr, 1, x), y);
    85478518
    8548     case C_CPLXNUM_TYPE_HASH:
    8549     {
    8550       C_word real_sum = C_s_a_i_plus(ptr, 2, x, C_u_i_cplxnum_real(y)),
    8551         imag = C_u_i_cplxnum_imag(y);
    8552       if (C_truep(C_u_i_inexactp(real_sum)))
    8553         imag = C_a_i_exact_to_inexact(ptr, 1, imag);
    8554       return C_cplxnum(ptr, real_sum, imag);
    8555     }
     8519  case C_dyadic_hash(C_RATNUM_TYPE_HASH, C_RATNUM_TYPE_HASH):
     8520    return rat_plusmin_rat(ptr, x, y, C_s_a_u_i_integer_plus);
    85568521
    8557     default:
    8558       barf(C_BAD_ARGUMENT_TYPE_NO_NUMBER_ERROR, "+", y);
    8559     }
     8522  case C_dyadic_hash(C_RATNUM_TYPE_HASH, C_CPLXNUM_TYPE_HASH):
     8523  {
     8524    C_word real_sum = C_s_a_i_plus(ptr, 2, x, C_u_i_cplxnum_real(y)),
     8525      imag = C_u_i_cplxnum_imag(y);
     8526    if (C_truep(C_u_i_inexactp(real_sum)))
     8527      imag = C_a_i_exact_to_inexact(ptr, 1, imag);
     8528    return C_cplxnum(ptr, real_sum, imag);
     8529  }
    85608530
    8561   case C_CPLXNUM_TYPE_HASH:
    8562     if (!C_immediatep(y) && C_block_header(y) == C_CPLXNUM_TAG) {
     8531  case C_dyadic_hash(C_CPLXNUM_TYPE_HASH, C_CPLXNUM_TYPE_HASH):
     8532  {
    85638533      C_word real_sum, imag_sum;
    85648534      real_sum = C_s_a_i_plus(ptr, 2, C_u_i_cplxnum_real(x), C_u_i_cplxnum_real(y));
    85658535      imag_sum = C_s_a_i_plus(ptr, 2, C_u_i_cplxnum_imag(x), C_u_i_cplxnum_imag(y));
    85668536      if (C_truep(C_u_i_zerop2(imag_sum))) return real_sum;
    85678537      else return C_cplxnum(ptr, real_sum, imag_sum);
    8568     } else {
    8569       C_word real_sum = C_s_a_i_plus(ptr, 2, C_u_i_cplxnum_real(x), y),
    8570         imag = C_u_i_cplxnum_imag(x);
    8571       if (C_truep(C_u_i_inexactp(real_sum)))
    8572         imag = C_a_i_exact_to_inexact(ptr, 1, imag);
    8573       return C_cplxnum(ptr, real_sum, imag);
    8574     }
     8538  }
     8539
     8540  case C_dyadic_hash(C_CPLXNUM_TYPE_HASH, C_FIXNUM_TYPE_HASH):
     8541  case C_dyadic_hash(C_CPLXNUM_TYPE_HASH, C_FLONUM_TYPE_HASH):
     8542  case C_dyadic_hash(C_CPLXNUM_TYPE_HASH, C_BIGNUM_TYPE_HASH):
     8543  case C_dyadic_hash(C_CPLXNUM_TYPE_HASH, C_RATNUM_TYPE_HASH):
     8544  {
     8545    C_word real_sum = C_s_a_i_plus(ptr, 2, C_u_i_cplxnum_real(x), y),
     8546      imag = C_u_i_cplxnum_imag(x);
     8547    if (C_truep(C_u_i_inexactp(real_sum)))
     8548      imag = C_a_i_exact_to_inexact(ptr, 1, imag);
     8549    return C_cplxnum(ptr, real_sum, imag);
     8550  }
    85758551
    85768552  default:
    8577     barf(C_BAD_ARGUMENT_TYPE_NO_NUMBER_ERROR, "+", x);
     8553    if (!C_truep(C_i_numberp(x)))
     8554      barf(C_BAD_ARGUMENT_TYPE_NO_NUMBER_ERROR, "+", x);
     8555    else
     8556      barf(C_BAD_ARGUMENT_TYPE_NO_NUMBER_ERROR, "+", y);
    85788557  }
    85798558}
    85808559
    static C_word bignum_minus_unsigned(C_word **ptr, C_word x, C_word y) 
    86888667C_regparm C_word C_fcall
    86898668C_s_a_i_minus(C_word **ptr, C_word n, C_word x, C_word y)
    86908669{
    8691   switch(C_type_hash(x)) { /* TODO: Use dyadic_hash? */
    8692   case C_FIXNUM_TYPE_HASH:
    8693     switch(C_type_hash(y)) {
    8694     case C_FIXNUM_TYPE_HASH:
    8695       return C_a_i_fixnum_difference(ptr, 2, x, y);
    8696 
    8697     case C_FLONUM_TYPE_HASH:
    8698       return C_flonum(ptr, (double)C_unfix(x) - C_flonum_magnitude(y));
    8699 
    8700     case C_BIGNUM_TYPE_HASH:
    8701       return C_s_a_u_i_integer_minus(ptr, 2, x, y);
     8670  switch(C_dyadic_hash(C_type_hash(x), C_type_hash(y))) {
     8671  case C_dyadic_hash(C_FIXNUM_TYPE_HASH, C_FIXNUM_TYPE_HASH):
     8672    return C_a_i_fixnum_difference(ptr, 2, x, y);
    87028673
    8703     case C_RATNUM_TYPE_HASH:
    8704       return integer_minus_rat(ptr, x, y);
     8674  case C_dyadic_hash(C_FIXNUM_TYPE_HASH, C_FLONUM_TYPE_HASH):
     8675    return C_flonum(ptr, (double)C_unfix(x) - C_flonum_magnitude(y));
    87058676
    8706     case C_CPLXNUM_TYPE_HASH:
    8707     {
    8708       C_word real_diff = C_s_a_i_minus(ptr, 2, x, C_u_i_cplxnum_real(y)),
    8709              imag = C_s_a_i_negate(ptr, 1, C_u_i_cplxnum_imag(y));
    8710       if (C_truep(C_u_i_inexactp(real_diff)))
    8711         imag = C_a_i_exact_to_inexact(ptr, 1, imag);
    8712       return C_cplxnum(ptr, real_diff, imag);
    8713     }
    8714 
    8715     default:
    8716       barf(C_BAD_ARGUMENT_TYPE_NO_NUMBER_ERROR, "-", y);
    8717     }
     8677  case C_dyadic_hash(C_FIXNUM_TYPE_HASH, C_BIGNUM_TYPE_HASH):
     8678    return C_s_a_u_i_integer_minus(ptr, 2, x, y);
    87188679
    8719   case C_FLONUM_TYPE_HASH:
    8720     switch(C_type_hash(y)) {
    8721     case C_FIXNUM_TYPE_HASH:
    8722       return C_flonum(ptr, C_flonum_magnitude(x) - (double)C_unfix(y));
     8680  case C_dyadic_hash(C_FIXNUM_TYPE_HASH, C_RATNUM_TYPE_HASH):
     8681    return integer_minus_rat(ptr, x, y);
    87238682
    8724     case C_FLONUM_TYPE_HASH:
    8725       return C_a_i_flonum_difference(ptr, 2, x, y);
     8683  case C_dyadic_hash(C_FIXNUM_TYPE_HASH, C_CPLXNUM_TYPE_HASH):
     8684  {
     8685    C_word real_diff = C_s_a_i_minus(ptr, 2, x, C_u_i_cplxnum_real(y)),
     8686      imag = C_s_a_i_negate(ptr, 1, C_u_i_cplxnum_imag(y));
     8687    if (C_truep(C_u_i_inexactp(real_diff)))
     8688      imag = C_a_i_exact_to_inexact(ptr, 1, imag);
     8689    return C_cplxnum(ptr, real_diff, imag);
     8690  }
    87268691
    8727     case C_BIGNUM_TYPE_HASH:
    8728       return C_flonum(ptr, C_flonum_magnitude(x)-C_bignum_to_double(y));
     8692  case C_dyadic_hash(C_FLONUM_TYPE_HASH, C_FIXNUM_TYPE_HASH):
     8693    return C_flonum(ptr, C_flonum_magnitude(x) - (double)C_unfix(y));
    87298694
    8730     case C_RATNUM_TYPE_HASH:
    8731       return C_s_a_i_minus(ptr, 2, x, C_a_i_exact_to_inexact(ptr, 1, y));
     8695  case C_dyadic_hash(C_FLONUM_TYPE_HASH, C_FLONUM_TYPE_HASH):
     8696    return C_a_i_flonum_difference(ptr, 2, x, y);
    87328697
    8733     case C_CPLXNUM_TYPE_HASH:
    8734     {
    8735       C_word real_diff = C_s_a_i_minus(ptr, 2, x, C_u_i_cplxnum_real(y)),
    8736              imag = C_s_a_i_negate(ptr, 1, C_u_i_cplxnum_imag(y));
    8737       if (C_truep(C_u_i_inexactp(real_diff)))
    8738         imag = C_a_i_exact_to_inexact(ptr, 1, imag);
    8739       return C_cplxnum(ptr, real_diff, imag);
    8740     }
     8698  case C_dyadic_hash(C_FLONUM_TYPE_HASH, C_BIGNUM_TYPE_HASH):
     8699    return C_flonum(ptr, C_flonum_magnitude(x)-C_bignum_to_double(y));
    87418700
    8742     default:
    8743       barf(C_BAD_ARGUMENT_TYPE_NO_NUMBER_ERROR, "-", y);
    8744     }
     8701  case C_dyadic_hash(C_FLONUM_TYPE_HASH, C_RATNUM_TYPE_HASH):
     8702    return C_s_a_i_minus(ptr, 2, x, C_a_i_exact_to_inexact(ptr, 1, y));
    87458703
    8746   case C_BIGNUM_TYPE_HASH:
    8747     switch(C_type_hash(y)) {
    8748     case C_FIXNUM_TYPE_HASH:
    8749       return C_s_a_u_i_integer_minus(ptr, 2, x, y);
     8704  case C_dyadic_hash(C_FLONUM_TYPE_HASH, C_CPLXNUM_TYPE_HASH):
     8705  {
     8706    C_word real_diff = C_s_a_i_minus(ptr, 2, x, C_u_i_cplxnum_real(y)),
     8707      imag = C_s_a_i_negate(ptr, 1, C_u_i_cplxnum_imag(y));
     8708    if (C_truep(C_u_i_inexactp(real_diff)))
     8709      imag = C_a_i_exact_to_inexact(ptr, 1, imag);
     8710    return C_cplxnum(ptr, real_diff, imag);
     8711  }
    87508712
    8751     case C_FLONUM_TYPE_HASH:
    8752       return C_flonum(ptr, C_bignum_to_double(x)-C_flonum_magnitude(y));
     8713  case C_dyadic_hash(C_BIGNUM_TYPE_HASH, C_FIXNUM_TYPE_HASH):
     8714    return C_s_a_u_i_integer_minus(ptr, 2, x, y);
    87538715
    8754     case C_BIGNUM_TYPE_HASH:
    8755       return C_s_a_u_i_integer_minus(ptr, 2, x, y);
     8716  case C_dyadic_hash(C_BIGNUM_TYPE_HASH, C_FLONUM_TYPE_HASH):
     8717    return C_flonum(ptr, C_bignum_to_double(x)-C_flonum_magnitude(y));
    87568718
    8757     case C_RATNUM_TYPE_HASH:
    8758       return integer_minus_rat(ptr, x, y);
     8719  case C_dyadic_hash(C_BIGNUM_TYPE_HASH, C_BIGNUM_TYPE_HASH):
     8720    return C_s_a_u_i_integer_minus(ptr, 2, x, y);
    87598721
    8760     case C_CPLXNUM_TYPE_HASH:
    8761     {
    8762       C_word real_diff = C_s_a_i_minus(ptr, 2, x, C_u_i_cplxnum_real(y)),
    8763              imag = C_s_a_i_negate(ptr, 1, C_u_i_cplxnum_imag(y));
    8764       if (C_truep(C_u_i_inexactp(real_diff)))
    8765         imag = C_a_i_exact_to_inexact(ptr, 1, imag);
    8766       return C_cplxnum(ptr, real_diff, imag);
    8767     }
     8722  case C_dyadic_hash(C_BIGNUM_TYPE_HASH, C_RATNUM_TYPE_HASH):
     8723    return integer_minus_rat(ptr, x, y);
    87688724
    8769     default:
    8770       barf(C_BAD_ARGUMENT_TYPE_NO_NUMBER_ERROR, "-", y);
    8771     }
     8725  case C_dyadic_hash(C_BIGNUM_TYPE_HASH, C_CPLXNUM_TYPE_HASH):
     8726  {
     8727    C_word real_diff = C_s_a_i_minus(ptr, 2, x, C_u_i_cplxnum_real(y)),
     8728      imag = C_s_a_i_negate(ptr, 1, C_u_i_cplxnum_imag(y));
     8729    if (C_truep(C_u_i_inexactp(real_diff)))
     8730      imag = C_a_i_exact_to_inexact(ptr, 1, imag);
     8731    return C_cplxnum(ptr, real_diff, imag);
     8732  }
    87728733
    8773   case C_RATNUM_TYPE_HASH:
    8774     switch(C_type_hash(y)) {
    8775     case C_FIXNUM_TYPE_HASH:
    8776       return rat_plusmin_integer(ptr, x, y, C_s_a_u_i_integer_minus);
     8734  case C_dyadic_hash(C_RATNUM_TYPE_HASH, C_FIXNUM_TYPE_HASH):
     8735    return rat_plusmin_integer(ptr, x, y, C_s_a_u_i_integer_minus);
    87778736
    8778     case C_FLONUM_TYPE_HASH:
    8779       return C_s_a_i_minus(ptr, 2, C_a_i_exact_to_inexact(ptr, 1, x), y);
     8737  case C_dyadic_hash(C_RATNUM_TYPE_HASH, C_FLONUM_TYPE_HASH):
     8738    return C_s_a_i_minus(ptr, 2, C_a_i_exact_to_inexact(ptr, 1, x), y);
    87808739
    8781     case C_BIGNUM_TYPE_HASH:
    8782       return rat_plusmin_integer(ptr, x, y, C_s_a_u_i_integer_minus);
     8740  case C_dyadic_hash(C_RATNUM_TYPE_HASH, C_BIGNUM_TYPE_HASH):
     8741    return rat_plusmin_integer(ptr, x, y, C_s_a_u_i_integer_minus);
    87838742
    8784     case C_RATNUM_TYPE_HASH:
    8785       return rat_plusmin_rat(ptr, x, y, C_s_a_u_i_integer_minus);
     8743  case C_dyadic_hash(C_RATNUM_TYPE_HASH, C_RATNUM_TYPE_HASH):
     8744    return rat_plusmin_rat(ptr, x, y, C_s_a_u_i_integer_minus);
    87868745
    8787     case C_CPLXNUM_TYPE_HASH:
    8788     {
    8789       C_word real_diff = C_s_a_i_minus(ptr, 2, x, C_u_i_cplxnum_real(y)),
    8790              imag = C_s_a_i_negate(ptr, 1, C_u_i_cplxnum_imag(y));
    8791       if (C_truep(C_u_i_inexactp(real_diff)))
    8792         imag = C_a_i_exact_to_inexact(ptr, 1, imag);
    8793       return C_cplxnum(ptr, real_diff, imag);
    8794     }
     8746  case C_dyadic_hash(C_RATNUM_TYPE_HASH, C_CPLXNUM_TYPE_HASH):
     8747  {
     8748    C_word real_diff = C_s_a_i_minus(ptr, 2, x, C_u_i_cplxnum_real(y)),
     8749      imag = C_s_a_i_negate(ptr, 1, C_u_i_cplxnum_imag(y));
     8750    if (C_truep(C_u_i_inexactp(real_diff)))
     8751      imag = C_a_i_exact_to_inexact(ptr, 1, imag);
     8752    return C_cplxnum(ptr, real_diff, imag);
     8753  }
    87958754
    8796     default:
    8797       barf(C_BAD_ARGUMENT_TYPE_NO_NUMBER_ERROR, "-", y);
    8798     }
     8755  case C_dyadic_hash(C_CPLXNUM_TYPE_HASH, C_CPLXNUM_TYPE_HASH):
     8756  {
     8757    C_word real_diff, imag_diff;
     8758    real_diff = C_s_a_i_minus(ptr,2,C_u_i_cplxnum_real(x),C_u_i_cplxnum_real(y));
     8759    imag_diff = C_s_a_i_minus(ptr,2,C_u_i_cplxnum_imag(x),C_u_i_cplxnum_imag(y));
     8760    if (C_truep(C_u_i_zerop2(imag_diff))) return real_diff;
     8761    else return C_cplxnum(ptr, real_diff, imag_diff);
     8762  }
    87998763
    8800   case C_CPLXNUM_TYPE_HASH:
    8801     if (!C_immediatep(y) && C_block_header(y) == C_CPLXNUM_TAG) {
    8802       C_word real_diff, imag_diff;
    8803       real_diff = C_s_a_i_minus(ptr,2,C_u_i_cplxnum_real(x),C_u_i_cplxnum_real(y));
    8804       imag_diff = C_s_a_i_minus(ptr,2,C_u_i_cplxnum_imag(x),C_u_i_cplxnum_imag(y));
    8805       if (C_truep(C_u_i_zerop2(imag_diff))) return real_diff;
    8806       else return C_cplxnum(ptr, real_diff, imag_diff);
    8807     } else {
    8808       C_word real_diff = C_s_a_i_minus(ptr, 2, C_u_i_cplxnum_real(x), y),
    8809              imag = C_u_i_cplxnum_imag(x);
    8810       if (C_truep(C_u_i_inexactp(real_diff)))
    8811         imag = C_a_i_exact_to_inexact(ptr, 1, imag);
    8812       return C_cplxnum(ptr, real_diff, imag);
    8813     }
     8764  case C_dyadic_hash(C_CPLXNUM_TYPE_HASH, C_FIXNUM_TYPE_HASH):
     8765  case C_dyadic_hash(C_CPLXNUM_TYPE_HASH, C_FLONUM_TYPE_HASH):
     8766  case C_dyadic_hash(C_CPLXNUM_TYPE_HASH, C_BIGNUM_TYPE_HASH):
     8767  case C_dyadic_hash(C_CPLXNUM_TYPE_HASH, C_RATNUM_TYPE_HASH):
     8768  {
     8769    C_word real_diff = C_s_a_i_minus(ptr, 2, C_u_i_cplxnum_real(x), y),
     8770      imag = C_u_i_cplxnum_imag(x);
     8771    if (C_truep(C_u_i_inexactp(real_diff)))
     8772      imag = C_a_i_exact_to_inexact(ptr, 1, imag);
     8773    return C_cplxnum(ptr, real_diff, imag);
     8774  }
    88148775
    88158776  default:
    8816     barf(C_BAD_ARGUMENT_TYPE_NO_NUMBER_ERROR, "-", x);
     8777    if (!C_truep(C_i_numberp(x)))
     8778      barf(C_BAD_ARGUMENT_TYPE_NO_NUMBER_ERROR, "-", x);
     8779    else
     8780      barf(C_BAD_ARGUMENT_TYPE_NO_NUMBER_ERROR, "-", y);
    88178781  }
    88188782}
    88198783
    static C_word flo_rat_cmp(C_word flonum, C_word ratnum) 
    97229686 */
    97239687static C_word basic_cmp(C_word x, C_word y, char *loc, int eqp)
    97249688{
    9725   switch(C_type_hash(x)) { /* TODO: Use dyadic_hash? */
    9726   case C_FIXNUM_TYPE_HASH:
    9727     switch(C_type_hash(y)) {
    9728     case C_FIXNUM_TYPE_HASH:
    9729       return C_fix((x < y) ? -1 : ((x > y) ? 1 : 0));
     9689  switch(C_dyadic_hash(C_type_hash(x), C_type_hash(y))) {
     9690  case C_dyadic_hash(C_FIXNUM_TYPE_HASH, C_FIXNUM_TYPE_HASH):
     9691    return C_fix((x < y) ? -1 : ((x > y) ? 1 : 0));
    97309692
    9731     case C_FLONUM_TYPE_HASH:
    9732       return int_flo_cmp(x, y);
     9693  case C_dyadic_hash(C_FIXNUM_TYPE_HASH, C_FLONUM_TYPE_HASH):
     9694    return int_flo_cmp(x, y);
    97339695
    9734     case C_BIGNUM_TYPE_HASH:
    9735     {
    9736       C_word ab[C_SIZEOF_FIX_BIGNUM], *a = ab;
    9737       return C_i_bignum_cmp(C_a_u_i_fix_to_big(&a, x), y);
    9738     }
     9696  case C_dyadic_hash(C_FIXNUM_TYPE_HASH, C_BIGNUM_TYPE_HASH):
     9697  {
     9698    C_word ab[C_SIZEOF_FIX_BIGNUM], *a = ab;
     9699    return C_i_bignum_cmp(C_a_u_i_fix_to_big(&a, x), y);
     9700  }
    97399701
    9740     case C_RATNUM_TYPE_HASH:
    9741       if (eqp) return C_SCHEME_FALSE;
    9742       else return rat_cmp(x, y);
     9702  case C_dyadic_hash(C_FIXNUM_TYPE_HASH, C_RATNUM_TYPE_HASH):
     9703    if (eqp) return C_SCHEME_FALSE;
     9704    else return rat_cmp(x, y);
    97439705
    9744     case C_CPLXNUM_TYPE_HASH:
    9745       if (eqp) return C_SCHEME_FALSE;
    9746       else barf(C_BAD_ARGUMENT_TYPE_COMPLEX_NO_ORDERING_ERROR, loc, y);
     9706  case C_dyadic_hash(C_FIXNUM_TYPE_HASH, C_CPLXNUM_TYPE_HASH):
     9707    if (eqp) return C_SCHEME_FALSE;
     9708    else barf(C_BAD_ARGUMENT_TYPE_COMPLEX_NO_ORDERING_ERROR, loc, y);
    97479709
    9748     default:
    9749       barf(C_BAD_ARGUMENT_TYPE_NO_NUMBER_ERROR, loc, y);
    9750     }
    9751 
    9752   case C_FLONUM_TYPE_HASH:
    9753     switch(C_type_hash(y)) {
    9754     case C_FIXNUM_TYPE_HASH:
    9755       return flo_int_cmp(x, y);
    97569710
    9757     case C_FLONUM_TYPE_HASH:
    9758     {
    9759       double a = C_flonum_magnitude(x), b = C_flonum_magnitude(y);
    9760       if (C_isnan(a) || C_isnan(b)) return C_SCHEME_FALSE; /* "mu" */
    9761       else return C_fix((a < b) ? -1 : ((a > b) ? 1 : 0));
    9762     }
     9711  case C_dyadic_hash(C_FLONUM_TYPE_HASH, C_FIXNUM_TYPE_HASH):
     9712    return flo_int_cmp(x, y);
    97639713
    9764     case C_BIGNUM_TYPE_HASH:
    9765       return flo_int_cmp(x, y);
     9714  case C_dyadic_hash(C_FLONUM_TYPE_HASH, C_FLONUM_TYPE_HASH):
     9715  {
     9716    double a = C_flonum_magnitude(x), b = C_flonum_magnitude(y);
     9717    if (C_isnan(a) || C_isnan(b)) return C_SCHEME_FALSE; /* "mu" */
     9718    else return C_fix((a < b) ? -1 : ((a > b) ? 1 : 0));
     9719  }
    97669720
    9767     case C_RATNUM_TYPE_HASH:
    9768       return flo_rat_cmp(x, y);
     9721  case C_dyadic_hash(C_FLONUM_TYPE_HASH, C_BIGNUM_TYPE_HASH):
     9722    return flo_int_cmp(x, y);
    97699723
    9770     case C_CPLXNUM_TYPE_HASH:
    9771       if (eqp) return C_SCHEME_FALSE;
    9772       else barf(C_BAD_ARGUMENT_TYPE_COMPLEX_NO_ORDERING_ERROR, loc, y);
     9724  case C_dyadic_hash(C_FLONUM_TYPE_HASH, C_RATNUM_TYPE_HASH):
     9725    return flo_rat_cmp(x, y);
    97739726
    9774     default:
    9775       barf(C_BAD_ARGUMENT_TYPE_NO_NUMBER_ERROR, loc, y);
    9776     }
     9727  case C_dyadic_hash(C_FLONUM_TYPE_HASH, C_CPLXNUM_TYPE_HASH):
     9728    if (eqp) return C_SCHEME_FALSE;
     9729    else barf(C_BAD_ARGUMENT_TYPE_COMPLEX_NO_ORDERING_ERROR, loc, y);
    97779730
    9778   case C_BIGNUM_TYPE_HASH:
    9779     switch(C_type_hash(y)) {
    9780     case C_FIXNUM_TYPE_HASH:
    9781     {
    9782       C_word ab[C_SIZEOF_FIX_BIGNUM], *a = ab;
    9783       return C_i_bignum_cmp(x, C_a_u_i_fix_to_big(&a, y));
    9784     }
     9731  case C_dyadic_hash(C_BIGNUM_TYPE_HASH, C_FIXNUM_TYPE_HASH):
     9732  {
     9733    C_word ab[C_SIZEOF_FIX_BIGNUM], *a = ab;
     9734    return C_i_bignum_cmp(x, C_a_u_i_fix_to_big(&a, y));
     9735  }
    97859736
    9786     case C_FLONUM_TYPE_HASH:
    9787       return int_flo_cmp(x, y);
     9737  case C_dyadic_hash(C_BIGNUM_TYPE_HASH, C_FLONUM_TYPE_HASH):
     9738    return int_flo_cmp(x, y);
    97889739
    9789     case C_BIGNUM_TYPE_HASH:
    9790       return C_i_bignum_cmp(x, y);
     9740  case C_dyadic_hash(C_BIGNUM_TYPE_HASH, C_BIGNUM_TYPE_HASH):
     9741    return C_i_bignum_cmp(x, y);
    97919742
    9792     case C_RATNUM_TYPE_HASH:
    9793       if (eqp) return C_SCHEME_FALSE;
    9794       else return rat_cmp(x, y);
     9743  case C_dyadic_hash(C_BIGNUM_TYPE_HASH, C_RATNUM_TYPE_HASH):
     9744    if (eqp) return C_SCHEME_FALSE;
     9745    else return rat_cmp(x, y);
    97959746
    9796     case C_CPLXNUM_TYPE_HASH:
    9797       if (eqp) return C_SCHEME_FALSE;
    9798       else barf(C_BAD_ARGUMENT_TYPE_COMPLEX_NO_ORDERING_ERROR, loc, y);
     9747  case C_dyadic_hash(C_BIGNUM_TYPE_HASH, C_CPLXNUM_TYPE_HASH):
     9748    if (eqp) return C_SCHEME_FALSE;
     9749    else barf(C_BAD_ARGUMENT_TYPE_COMPLEX_NO_ORDERING_ERROR, loc, y);
    97999750
    9800     default:
    9801       barf(C_BAD_ARGUMENT_TYPE_NO_NUMBER_ERROR, loc, y);
    9802     }
     9751  case C_dyadic_hash(C_RATNUM_TYPE_HASH, C_FIXNUM_TYPE_HASH):
     9752    if (eqp) return C_SCHEME_FALSE;
     9753    else return rat_cmp(x, y);
    98039754
    9804   case C_RATNUM_TYPE_HASH:
    9805     switch(C_type_hash(y)) {
    9806     case C_FIXNUM_TYPE_HASH:
    9807       if (eqp) return C_SCHEME_FALSE;
    9808       else return rat_cmp(x, y);
    9809 
    9810     case C_FLONUM_TYPE_HASH:
    9811       return rat_flo_cmp(x, y);
    9812 
    9813     case C_BIGNUM_TYPE_HASH:
    9814       if (eqp) return C_SCHEME_FALSE;
    9815       else return rat_cmp(x, y);
    9816 
    9817     case C_RATNUM_TYPE_HASH:
    9818       if (eqp) {
    9819         return C_and(C_and(C_i_integer_equalp(C_u_i_ratnum_num(x),
    9820                                               C_u_i_ratnum_num(y)),
    9821                            C_i_integer_equalp(C_u_i_ratnum_denom(x),
    9822                                               C_u_i_ratnum_denom(y))),
    9823                      C_fix(0));
    9824       } else {
    9825         return rat_cmp(x, y);
    9826       }
     9755  case C_dyadic_hash(C_RATNUM_TYPE_HASH, C_FLONUM_TYPE_HASH):
     9756    return rat_flo_cmp(x, y);
    98279757
    9828     case C_CPLXNUM_TYPE_HASH:
    9829       if (eqp) return C_SCHEME_FALSE;
    9830       else barf(C_BAD_ARGUMENT_TYPE_COMPLEX_NO_ORDERING_ERROR, loc, y);
     9758  case C_dyadic_hash(C_RATNUM_TYPE_HASH, C_BIGNUM_TYPE_HASH):
     9759    if (eqp) return C_SCHEME_FALSE;
     9760    else return rat_cmp(x, y);
    98319761
    9832     default:
    9833       barf(C_BAD_ARGUMENT_TYPE_NO_NUMBER_ERROR, loc, y);
     9762  case C_dyadic_hash(C_RATNUM_TYPE_HASH, C_RATNUM_TYPE_HASH):
     9763    if (eqp) {
     9764      return C_and(C_and(C_i_integer_equalp(C_u_i_ratnum_num(x),
     9765                                            C_u_i_ratnum_num(y)),
     9766                         C_i_integer_equalp(C_u_i_ratnum_denom(x),
     9767                                            C_u_i_ratnum_denom(y))),
     9768                   C_fix(0));
     9769    } else {
     9770      return rat_cmp(x, y);
    98349771    }
    98359772
    9836   case C_CPLXNUM_TYPE_HASH:
     9773  case C_dyadic_hash(C_RATNUM_TYPE_HASH, C_CPLXNUM_TYPE_HASH):
     9774    if (eqp) return C_SCHEME_FALSE;
     9775    else barf(C_BAD_ARGUMENT_TYPE_COMPLEX_NO_ORDERING_ERROR, loc, y);
     9776
     9777
     9778  case C_dyadic_hash(C_CPLXNUM_TYPE_HASH, C_FIXNUM_TYPE_HASH):
     9779  case C_dyadic_hash(C_CPLXNUM_TYPE_HASH, C_FLONUM_TYPE_HASH):
     9780  case C_dyadic_hash(C_CPLXNUM_TYPE_HASH, C_BIGNUM_TYPE_HASH):
     9781  case C_dyadic_hash(C_CPLXNUM_TYPE_HASH, C_RATNUM_TYPE_HASH):
    98379782    if (!eqp)
    98389783      barf(C_BAD_ARGUMENT_TYPE_COMPLEX_NO_ORDERING_ERROR, loc, x);
    9839 
    9840     switch(C_type_hash(y)) {
    9841     case C_FIXNUM_TYPE_HASH:
    9842     case C_FLONUM_TYPE_HASH:
    9843     case C_BIGNUM_TYPE_HASH:
    9844     case C_RATNUM_TYPE_HASH:
     9784    else
    98459785      return C_SCHEME_FALSE;
    98469786
    9847     case C_CPLXNUM_TYPE_HASH:
     9787  case C_dyadic_hash(C_CPLXNUM_TYPE_HASH, C_CPLXNUM_TYPE_HASH):
     9788    if (!eqp)
     9789      barf(C_BAD_ARGUMENT_TYPE_COMPLEX_NO_ORDERING_ERROR, loc, x);
     9790    else
    98489791      return C_and(C_and(C_i_nequalp(C_u_i_cplxnum_real(x), C_u_i_cplxnum_real(y)),
    98499792                         C_i_nequalp(C_u_i_cplxnum_imag(x), C_u_i_cplxnum_imag(y))),
    98509793                   C_fix(0));
    98519794
    9852     default:
    9853       barf(C_BAD_ARGUMENT_TYPE_NO_NUMBER_ERROR, loc, y);
    9854     }
    9855 
    98569795  default:
    9857     barf(C_BAD_ARGUMENT_TYPE_NO_NUMBER_ERROR, loc, x);
     9796    if (!C_truep(C_i_numberp(x)))
     9797      barf(C_BAD_ARGUMENT_TYPE_NO_NUMBER_ERROR, loc, x);
     9798    else
     9799      barf(C_BAD_ARGUMENT_TYPE_NO_NUMBER_ERROR, loc, y);
    98589800  }
    98599801}
    98609802