I started hacking this because I thought I needed it, but that turned out not to be true. Should I finish it (it still needs tests), or is there some reason to hold off?
-- Bob Rogers http://rgrjr.dyndns.org/
* src/pmc/bigint.pmc: + (bigint_bitwise_and_bigint_bigint, bigint_bitwise_and_bigint_int): Bigint support for bitwise_and methods. + (bitwise_and, bitwise_and_int, i_bitwise_and, i_bitwise_and_int): Methods that extend the C<band> op to bigints. Diffs between last version checked in and current workfile(s): Index: src/pmc/bigint.pmc =================================================================== --- src/pmc/bigint.pmc (revision 18749) +++ src/pmc/bigint.pmc (working copy) @@ -285,7 +285,31 @@ else mpz_mul_2exp(BN(dest), BN(self), -value); } +static void +bigint_bitwise_and_bigint_bigint(Interp *interp, PMC* self, + PMC* value, PMC *dest) +{ + mpz_and(BN(dest), BN(self), BN(value)); +} +static void +bigint_bitwise_and_bigint_int(Interp *interp, PMC* self, + INTVAL value, PMC *dest) +/* This is is trickier than the BigInt/BigInt case, since we need to (a) produce + * a BigInt version of value, and (b) morph the result back to Integer. + */ +{ + mpz_t value_bn, result; + long iresult; + mpz_init(value_bn); + mpz_set_si(value_bn, value); + mpz_init(result); + mpz_and(result, BN(self), value_bn); + iresult = mpz_get_si(result); + VTABLE_morph(interp, dest, enum_class_Integer); + VTABLE_set_integer_native(interp, dest, iresult); +} + #else /* ifdef PARROT_HAS_GMP */ static void @@ -488,6 +512,21 @@ real_exception(interp, NULL, E_LibraryNotLoadedError, "no bigint lib loaded"); } +static void +bigint_bitwise_and_bigint_bigint(Interp *interp, PMC* self, + PMC* value, PMC *dest) +{ + real_exception(interp, NULL, E_LibraryNotLoadedError, + "no bigint lib loaded"); +} +static void +bigint_bitwise_and_bigint_int(Interp *interp, PMC* self, + INTVAL value, PMC *dest) + +{ + real_exception(interp, NULL, E_LibraryNotLoadedError, + "no bigint lib loaded"); +} #endif /* ifdef PARROT_HAS_GMP */ pmclass BigInt { @@ -1309,6 +1348,68 @@ bigint_bitwise_shr_bigint_int(INTERP, SELF, value, SELF); } +/* + +=item C<PMC* bitwise_and(PMC *value, PMC *dest)> + +=item C<PMC* bitwise_and_int(INTVAL value, PMC *dest)> + +Returns in C<*dest> the bitwise AND of the BigInt by C<*value>. + +=item C<void i_bitwise_and(PMC *value)> + +=item C<void i_bitwise_and_int(INTVAL value)> + +Inplace bitwise AND. + +=cut + +*/ + + PMC* bitwise_and(PMC* value, PMC* dest) { +MMD_BigInt: { + if (dest) + VTABLE_morph(interp, dest, SELF->vtable->base_type); + else + dest = pmc_new(INTERP, SELF->vtable->base_type); + bigint_bitwise_and_bigint_bigint(INTERP, SELF, value, dest); + return dest; + } +MMD_Integer: { + if (! dest) + dest = pmc_new(INTERP, SELF->vtable->base_type); + bigint_bitwise_and_bigint_int(INTERP, SELF, PMC_int_val(value), dest); + return dest; + } +MMD_DEFAULT: { + real_exception(INTERP, NULL, E_NotImplementedError, "unimp band"); + return dest; + } + } + + PMC* bitwise_and_int(INTVAL value, PMC* dest) { + if (! dest) + dest = pmc_new(INTERP, SELF->vtable->base_type); + bigint_bitwise_and_bigint_int(INTERP, SELF, value, dest); + return dest; + } + + void i_bitwise_and(PMC* value) { +MMD_BigInt: { + bigint_bitwise_and_bigint_bigint(INTERP, SELF, value, SELF); + } +MMD_Integer: { + bigint_bitwise_and_bigint_int(INTERP, SELF, PMC_int_val(value), SELF); + } +MMD_DEFAULT: { + real_exception(INTERP, NULL, E_NotImplementedError, "unimp band"); + } + } + + void i_bitwise_and_int(INTVAL value) { + bigint_bitwise_and_bigint_int(INTERP, SELF, value, SELF); + } + } /* End of diffs.