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.