static int sexp_object_compare (sexp ctx, sexp a, sexp b) { int res; if (a == b) return 0; if (sexp_pointerp(a)) { if (sexp_pointerp(b)) { if (sexp_pointer_tag(a) != sexp_pointer_tag(b)) { res = sexp_pointer_tag(a) - sexp_pointer_tag(b); } else { switch (sexp_pointer_tag(a)) { case SEXP_FLONUM: res = sexp_flonum_value(a) - sexp_flonum_value(b); break; case SEXP_BIGNUM: res = sexp_bignum_compare(a, b); break; case SEXP_STRING: res = strcmp(sexp_string_data(a), sexp_string_data(b)); break; case SEXP_SYMBOL: res = strcmp(sexp_symbol_data(a), sexp_symbol_data(b)); break; default: res = 0; break; } } #if SEXP_USE_HUFF_SYMS } else if (sexp_lsymbolp(a) && sexp_isymbolp(b)) { res = strcmp(sexp_symbol_data(a), sexp_string_data(sexp_write_to_string(ctx, b))); #endif } else { res = 1; } } else if (sexp_pointerp(b)) { #if SEXP_USE_HUFF_SYMS if (sexp_isymbolp(a) && sexp_lsymbolp(b)) res = strcmp(sexp_string_data(sexp_write_to_string(ctx, a)), sexp_symbol_data(b)); else #endif res = -1; } else { #if SEXP_USE_HUFF_SYMS if (sexp_isymbolp(a) && sexp_isymbolp(b)) return sexp_isymbol_compare(ctx, a, b); else #endif res = (sexp_sint_t)a - (sexp_sint_t)b; } return res; }
static sexp quot_step (sexp ctx, sexp *rem, sexp a, sexp b, sexp k, sexp i) { sexp res; sexp_gc_var5(x, prod, diff, k2, i2); if (sexp_bignum_compare(k, a) > 0) { *rem = a; return sexp_fixnum_to_bignum(ctx, SEXP_ZERO); } sexp_gc_preserve5(ctx, x, prod, diff, k2, i2); k2 = sexp_bignum_double(ctx, k); i2 = sexp_bignum_double(ctx, i); x = quot_step(ctx, rem, a, b, k2, i2); prod = sexp_bignum_mul(ctx, NULL, x, b); diff = sexp_bignum_sub_digits(ctx, NULL, a, prod); if (sexp_bignum_compare(diff, k) >= 0) { *rem = sexp_bignum_sub_digits(ctx, NULL, diff, k); res = sexp_bignum_add_digits(ctx, NULL, x, i); } else { *rem = diff; res = x; } sexp_gc_release5(ctx); return res; }