Adds tests and fixes incorrect implementation.

Kevin Tew
Index: classes/bigint.pmc
===================================================================
--- classes/bigint.pmc	(revision 8168)
+++ classes/bigint.pmc	(working copy)
@@ -203,44 +203,11 @@
 }
 
 static void
-bigint_bitwise_shl_bigint(Interp *interpreter, PMC* self, PMC *value, PMC *dest)
-{
-    mpz_t bn_1;
-    mpz_t bn_2;
-    mpz_init(bn_1);
-    mpz_init(bn_2);
-    mpz_set_ui(bn_1, 1);
-    mpz_set_ui(bn_2, 2);
-
-    mpz_powm(BN(dest), bn_2, BN(value), bn_1);
-    mpz_mul(BN(dest), BN(self), BN(dest));
-
-    mpz_clear(bn_1);
-    mpz_clear(bn_2);
-}
-static void
 bigint_bitwise_shl_bigint_int(Interp *interpreter, PMC* self, INTVAL value, PMC *dest)
 {
     mpz_mul_2exp(BN(dest), BN(self), value);
 }
-
 static void
-bigint_bitwise_shr_bigint(Interp *interpreter, PMC* self, PMC *value, PMC *dest)
-{
-    mpz_t bn_1;
-    mpz_t bn_2;
-    mpz_init(bn_1);
-    mpz_init(bn_2);
-    mpz_set_ui(bn_1, 1);
-    mpz_set_ui(bn_2, 2);
-
-    mpz_powm(BN(dest), bn_2, BN(value), bn_1);
-    mpz_fdiv_q(BN(dest), BN(self), BN(dest));
-
-    mpz_clear(bn_1);
-    mpz_clear(bn_2);
-}
-static void
 bigint_bitwise_shr_bigint_int(Interp *interpreter, PMC* self, INTVAL value, PMC *dest)
 {
     mpz_tdiv_q_2exp(BN(dest), BN(self), value);
@@ -1103,7 +1070,7 @@
                 VTABLE_morph(interpreter, dest, SELF->vtable->base_type);
             else
                 dest = pmc_new(INTERP, SELF->vtable->base_type);
-            bigint_bitwise_shl_bigint(INTERP, SELF, value, dest);
+            bigint_bitwise_shl_bigint_int(INTERP, SELF, VTABLE_get_integer(INTERP, value), dest);
             return dest;
         }
 MMD_Integer: {
@@ -1132,7 +1099,7 @@
 
     void i_bitwise_shl (PMC* value) {
 MMD_BigInt: {
-                bigint_bitwise_shl_bigint(INTERP, SELF, value, SELF);
+                bigint_bitwise_shl_bigint_int(INTERP, SELF, VTABLE_get_integer(INTERP, value), SELF);
             }
 MMD_Integer: {
                 bigint_bitwise_shl_bigint_int(INTERP, SELF, PMC_int_val(value), SELF);
@@ -1146,16 +1113,83 @@
         bigint_bitwise_shl_bigint_int(INTERP, SELF, value, SELF);
     }
 
+/*
+
+=item C<PMC* bitwise_shr(PMC *value, PMC *dest)>
+
+=item C<PMC* bitwise_shr_int(INTVAL value, PMC *dest)>
+
+Returns in C<*dest> the shift right of the BigInt by C<*value>.
+
+=item C<void i_bitwise_shr(PMC *value)>
+
+=item C<void i_bitwise_shr_int(INTVAL value)>
+
+Inplace shift left.
+
+=cut
+
+*/
+
+    PMC* bitwise_shr (PMC* value, PMC* dest) {
+MMD_BigInt: {
+            if (dest)
+                VTABLE_morph(interpreter, dest, SELF->vtable->base_type);
+            else
+                dest = pmc_new(INTERP, SELF->vtable->base_type);
+            bigint_bitwise_shr_bigint_int(INTERP, SELF, VTABLE_get_integer(INTERP, value), dest);
+            return dest;
+        }
+MMD_Integer: {
+            if (dest)
+                VTABLE_morph(interpreter, dest, SELF->vtable->base_type);
+            else
+                dest = pmc_new(INTERP, SELF->vtable->base_type);
+            bigint_bitwise_shr_bigint_int(INTERP, SELF, PMC_int_val(value), dest);
+            return dest;
+         }
+MMD_DEFAULT: {
+            internal_exception(1, "unimp shr");
+            return dest;
+         }
+    }
+
+    PMC* bitwise_shr_int (INTVAL value, PMC* dest) {
+        if (dest)
+            VTABLE_morph(interpreter, dest, SELF->vtable->base_type);
+        else
+            dest = pmc_new(INTERP, SELF->vtable->base_type);
+        bigint_bitwise_shr_bigint_int(INTERP, SELF, value, dest);
+        return dest;
+    }
+
+
+    void i_bitwise_shr (PMC* value) {
+MMD_BigInt: {
+                bigint_bitwise_shr_bigint_int(INTERP, SELF, VTABLE_get_integer(INTERP, value), SELF);
+            }
+MMD_Integer: {
+                bigint_bitwise_shr_bigint_int(INTERP, SELF, PMC_int_val(value), SELF);
+             }
+MMD_DEFAULT: {
+                internal_exception(1, "unimp shr");
+             }
+    }
+
+    void i_bitwise_shr_int (INTVAL value) {
+        bigint_bitwise_shr_bigint_int(INTERP, SELF, value, SELF);
+    }
+
 }
 
 /*
 
 =back
-
+  
 =cut
 
 */
-
+   
 /*
  * Local variables:
  * c-indentation-style: bsd
Index: t/pmc/bigint.t
===================================================================
--- t/pmc/bigint.t	(revision 8168)
+++ t/pmc/bigint.t	(working copy)
@@ -21,7 +21,7 @@
 use Parrot::Config;
 
 if ($PConfig{gmp}) {
-    plan tests => 22;
+    plan tests => 26;
 }
 else {
     plan skip_all => "No BigInt Lib configured";
@@ -657,3 +657,105 @@
 81857780532171226806613001927876611195909216420198
 
 OUTPUT
+
+output_is(<<'CODE', <<'OUT', "shl_bigint");
+   new P0, .BigInt
+   set P0, "2"
+   new P1, .BigInt
+   set P1, 2
+   new P2, .BigInt
+   shl P2, P0, P1
+   set S0, P2
+   print S0
+   print "\n"
+   set P0, "100000000000"
+   set P1, 10
+   shl P2, P0, P1
+   set S0, P2
+   print S0
+   print "\n"
+   end
+CODE
+8
+102400000000000
+OUT
+
+output_is(<<'CODE', <<'OUT', "shl_int");
+   new P0, .BigInt
+   set P0, 2
+   new P1, .Integer
+   set P1, 1
+   new P2, .BigInt
+   shl P2, P0, P1
+   set S0, P2
+   print S0
+   print "\n"
+   set P0, "100000000000"
+   set P1, 1
+   shl P2, P0, P1
+   set S0, P2
+   print S0
+   print "\n"
+   set P0, "100000000000"
+   set P1, 10
+   shl P2, P0, P1
+   set S0, P2
+   print S0
+   print "\n"
+   end
+CODE
+4
+200000000000
+102400000000000
+OUT
+
+output_is(<<'CODE', <<'OUT', "shr_bigint");
+   new P0, .BigInt
+   set P0, 8
+   new P1, .BigInt
+   set P1, 2
+   new P2, .BigInt
+   shr P2, P0, P1
+   set S0, P2
+   print S0
+   print "\n"
+   set P0, "102400000000000"
+   set P1, 10
+   shr P2, P0, P1
+   set S0, P2
+   print S0
+   print "\n"
+   end
+CODE
+2
+100000000000
+OUT
+
+output_is(<<'CODE', <<'OUT', "shr_int");
+   new P0, .BigInt
+   set P0, 4
+   new P1, .Integer
+   set P1, 1
+   new P2, .BigInt
+   shr P2, P0, P1
+   set S0, P2
+   print S0
+   print "\n"
+   set P0, "200000000000"
+   set P1, 1
+   shr P2, P0, P1
+   set S0, P2
+   print S0
+   print "\n"
+   set P0, "102400000000000"
+   set P1, 10
+   shr P2, P0, P1
+   set S0, P2
+   print S0
+   print "\n"
+   end
+CODE
+2
+100000000000
+100000000000
+OUT

Reply via email to