Author: leo
Date: Sun Apr 17 08:16:41 2005
New Revision: 7856

Modified:
   trunk/classes/bigint.pmc
   trunk/classes/float.pmc
   trunk/classes/integer.pmc
   trunk/classes/perlstring.pmc
   trunk/classes/perlundef.pmc
   trunk/classes/scalar.pmc
   trunk/dynclasses/pyfloat.pmc
   trunk/dynclasses/pyint.pmc
   trunk/dynclasses/pystring.pmc
   trunk/imcc/parser_util.c
   trunk/vtable.tbl
Log:
MMD 27 - convert cmod, mod, pow

Modified: trunk/classes/bigint.pmc
==============================================================================
--- trunk/classes/bigint.pmc    (original)
+++ trunk/classes/bigint.pmc    Sun Apr 17 08:16:41 2005
@@ -161,25 +161,13 @@
 static void
 bigint_mod_bigint(Interp *interpreter, PMC* self, PMC *value, PMC *dest)
 {
-    VTABLE_morph(interpreter, dest, enum_class_BigInt);
     mpz_mod(BN(dest), BN(self), BN(value));
-    if (mpz_fits_slong_p(BN(dest))) {
-        long iresult = mpz_get_si(BN(dest));
-        VTABLE_morph(interpreter, dest, enum_class_Integer);
-        VTABLE_set_integer_native(interpreter, dest, iresult);
-    }
 }
 
 static void
 bigint_mod_bigint_int(Interp *interpreter, PMC* self, INTVAL value, PMC *dest)
 {
-    VTABLE_morph(interpreter, dest, enum_class_BigInt);
     mpz_mod_ui(BN(dest), BN(self), value);
-    if (mpz_fits_slong_p(BN(dest))) {
-        long iresult = mpz_get_si(BN(dest));
-        VTABLE_morph(interpreter, dest, enum_class_Integer);
-        VTABLE_set_integer_native(interpreter, dest, iresult);
-    }
 }
 static INTVAL
 bigint_cmp(Interp *interpreter, PMC* self, PMC *value)
@@ -842,24 +830,59 @@
         bigint_fdiv_bigint_int(INTERP, SELF, value, SELF);
     }
 
-    void modulus(PMC* value, PMC* dest) {
+    PMC* modulus(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_mod_bigint(INTERP, SELF, 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_mod_bigint_int(INTERP, SELF, PMC_int_val(value), dest);
+            return dest;
+         }
+MMD_DEFAULT: {
+            internal_exception(1, "unimp mod");
+            return dest;
+        }
+    }
+
+    PMC* cmodulus(PMC* value, PMC* dest) {
+MMD_BigInt: {
+                return Parrot_BigInt_modulus_BigInt(INTERP, SELF, value, dest);
+            }
+MMD_Integer: {
+                return Parrot_BigInt_modulus_Integer(INTERP, SELF, value, 
dest);
+             }
+MMD_DEFAULT: {
+                return Parrot_BigInt_modulus(INTERP, SELF, value, dest);
+             }
+    }
+
+    void i_modulus(PMC* value) {
 MMD_BigInt: {
-                bigint_mod_bigint(INTERP, SELF, value, dest);
+                bigint_mod_bigint(INTERP, SELF, value, SELF);
             }
 MMD_Integer: {
-                bigint_mod_bigint_int(INTERP, SELF, PMC_int_val(value), dest);
+                bigint_mod_bigint_int(INTERP, SELF, PMC_int_val(value), SELF);
              }
 MMD_DEFAULT: {
                  internal_exception(1, "unimp mod");
              }
     }
 
-    void cmodulus(PMC* value, PMC* dest) {
+    void i_cmodulus(PMC* value) {
 MMD_BigInt: {
-                bigint_mod_bigint(INTERP, SELF, value, dest);
+                bigint_mod_bigint(INTERP, SELF, value, SELF);
             }
 MMD_Integer: {
-                bigint_mod_bigint_int(INTERP, SELF, PMC_int_val(value), dest);
+                bigint_mod_bigint_int(INTERP, SELF, PMC_int_val(value), SELF);
              }
 MMD_DEFAULT: {
                  internal_exception(1, "unimp cmod");

Modified: trunk/classes/float.pmc
==============================================================================
--- trunk/classes/float.pmc     (original)
+++ trunk/classes/float.pmc     Sun Apr 17 08:16:41 2005
@@ -250,113 +250,6 @@
             return SUPER(value);  /* XXX inheritance problem */
         }
     }
-/*
-
-=item C<void cmodulus(PMC *value, PMC *dest)>
-
-Calculates the value of the number C-style C<mod> C<*value> and returns
-the result in C<*dest>.
-
-=cut
-
-*/
-
-    void cmodulus (PMC* value, PMC* dest) {
-MMD_Float: {
-        /* TODO zero divide */
-        FLOATVAL f = PMC_num_val(value);
-        VTABLE_set_number_native(INTERP, dest,
-            fmod(PMC_num_val(SELF), f));
-        }
-MMD_DEFAULT: {
-        FLOATVAL f = VTABLE_get_number(INTERP, value);
-        VTABLE_set_number_native(INTERP, dest,
-            fmod(PMC_num_val(SELF), f));
-        }
-    }
-
-/*
-
-=item C<void cmodulus_float(FLOATVAL value, PMC *dest)>
-
-=cut
-
-*/
-
-    void cmodulus_float (FLOATVAL value, PMC* dest) {
-        VTABLE_set_number_native(INTERP, dest,
-            fmod(PMC_num_val(SELF), value));
-    }
-
-/*
-
-=item C<void cmodulus_int(INTVAL value, PMC *dest)>
-
-Calculates the value of the number C-style C<mod> C<value> and returns
-the result in C<*dest>.
-
-=cut
-
-*/
-
-    void cmodulus_int (INTVAL value, PMC* dest) {
-        VTABLE_set_number_native(INTERP, dest,
-            fmod(PMC_num_val(SELF), value));
-    }
-
-/*
-
-=item C<void modulus(PMC *value, PMC *dest)>
-
-Calculates the value of the number C<mod> C<*value> and returns the
-result in C<*dest>.
-
-=cut
-
-*/
-
-    void modulus (PMC* value, PMC* dest) {
-MMD_Float: {
-        /* TODO zero divide */
-        FLOATVAL f = PMC_num_val(value);
-        VTABLE_set_number_native(INTERP, dest,
-            floatval_mod(PMC_num_val(SELF), f));
-        }
-MMD_DEFAULT: {
-        FLOATVAL f = VTABLE_get_number(INTERP, value);
-        VTABLE_set_number_native(INTERP, dest,
-            floatval_mod(PMC_num_val(SELF), f));
-        }
-    }
-
-/*
-
-=item C<void modulus_float(FLOATVAL value, PMC *dest)>
-
-=cut
-
-*/
-
-    void modulus_float (FLOATVAL value, PMC* dest) {
-        VTABLE_set_number_native(INTERP, dest,
-            floatval_mod(PMC_num_val(SELF), value));
-    }
-
-/*
-
-=item C<void modulus_int(INTVAL value, PMC *dest)>
-
-Calculates the value of the number C<mod> C<value> and returns the
-result in C<*dest>.
-
-=cut
-
-*/
-
-    void modulus_int (INTVAL value, PMC* dest) {
-        VTABLE_set_number_native(INTERP, dest,
-            floatval_mod(PMC_num_val(SELF), value));
-    }
 
 /*
 

Modified: trunk/classes/integer.pmc
==============================================================================
--- trunk/classes/integer.pmc   (original)
+++ trunk/classes/integer.pmc   Sun Apr 17 08:16:41 2005
@@ -873,89 +873,262 @@
         VTABLE_set_integer_native(INTERP, SELF,
                 floor(DYNSELF.get_number() / value));
     }
+
 /*
 
-=item C<void pow_int(INTVAL value, PMC *dest)>
+=item C<PMC* cmodulus(PMC *value, PMC *dest)>
 
-Rise SELF to the C<value>th power.
+=item C<PMC* cmodulus(INTVAL value, PMC *dest)>
+
+=item C<PMC* cmodulus(FLOATVAL value, PMC *dest)>
+
+Calculates the value of the number C-style C<mod> C<value> and returns
+the result in C<dest>.
+
+=item C<void i_cmodulus(PMC *value)>
+
+=item C<void i_cmodulus(INTVAL value)>
+
+=item C<void i_cmodulus(FLOATVAL value)>
+
+Calculates the value of the number C-style C<mod> C<value> and returns
+the result in C<dest>.
 
 =cut
 
 */
 
-    void pow_int (INTVAL b, PMC* dest) {
-        INTVAL a = PMC_int_val(SELF);
-        INTVAL i;
-        VTABLE_set_integer_native(INTERP, dest, a);
-        --b;
-        for (i = 0; i < b; ++i) {
-            mmd_dispatch_v_pip(interpreter, dest, a, dest, MMD_MULTIPLY);
+    PMC* cmodulus (PMC* value, PMC* dest) {
+MMD_BigInt: {
+            return overflow_p(INTERP, SELF, value, dest, MMD_CMOD);
         }
+MMD_DEFAULT: {
+            INTVAL d = VTABLE_get_integer(INTERP, value);
 
+            if (d == 0.0)
+                real_exception(INTERP, NULL, E_ZeroDivisionError,
+                        "int cmodulus by zero");
+            if (!dest)
+                dest = pmc_new(INTERP, SELF->vtable->base_type);
+            VTABLE_set_integer_native(INTERP, dest,
+                    DYNSELF.get_integer() % d);
+            return dest;
+        }
     }
 
-/*
+    PMC* cmodulus_float (FLOATVAL value, PMC* dest) {
+        if (value == 0.0)
+            real_exception(INTERP, NULL, E_ZeroDivisionError,
+                    "int cmodulus by zero");
+        if (!dest)
+            dest = pmc_new(INTERP, SELF->vtable->base_type);
+        VTABLE_set_integer_native(INTERP, dest,
+                fmod(DYNSELF.get_integer(), value));
+        return dest;
+    }
 
-=item C<void cmodulus(PMC *value, PMC *dest)>
+    PMC* cmodulus_int (INTVAL value, PMC* dest) {
+        if (value == 0)
+            real_exception(INTERP, NULL, E_ZeroDivisionError,
+                    "int cmodulus by zero");
+        if (!dest)
+            dest = pmc_new(INTERP, SELF->vtable->base_type);
+        VTABLE_set_integer_native(INTERP, dest,
+                DYNSELF.get_integer() % value);
+        return dest;
+    }
 
-Calculates the value of the integer C-style C<mod> C<*value> and returns
-the result in C<*dest>.
+    void i_cmodulus (PMC* value) {
+MMD_BigInt: {
+             overflow_p(INTERP, SELF, value, SELF, MMD_CMOD);
+        }
+MMD_DEFAULT: {
+            INTVAL d = VTABLE_get_integer(INTERP, value);
 
-=cut
+            if (d == 0.0)
+                real_exception(INTERP, NULL, E_ZeroDivisionError,
+                        "int cmodulus by zero");
+            VTABLE_set_integer_native(INTERP, SELF,
+                    DYNSELF.get_integer() % d);
+        }
+    }
 
-*/
-    void cmodulus (PMC* value, PMC* dest) {
-        VTABLE_set_integer_native(INTERP, dest,
-                                  PMC_int_val(SELF) %
-                                  VTABLE_get_integer(INTERP, value));
+    void i_cmodulus_int (INTVAL value) {
+        if (value == 0)
+            real_exception(INTERP, NULL, E_ZeroDivisionError,
+                    "int cmodulus by zero");
+        VTABLE_set_integer_native(INTERP, SELF,
+                DYNSELF.get_integer() % value);
+    }
+
+    void i_cmodulus_float (FLOATVAL value) {
+        if (value == 0.0)
+            real_exception(INTERP, NULL, E_ZeroDivisionError,
+                    "int cmodulus by zero");
+        VTABLE_set_integer_native(INTERP, SELF,
+                fmod(DYNSELF.get_integer(), value));
     }
 
 /*
 
-=item C<void cmodulus_int(INTVAL value, PMC *dest) >
+=item C<PMC* modulus(PMC *value, PMC *dest)>
 
-Calculates the value of the integer C-style C<mod> C<value> and returns
-the result in C<*dest>.
+=item C<PMC* modulus(INTVAL value, PMC *dest)>
 
-=cut
+=item C<PMC* modulus(FLOATVAL value, PMC *dest)>
 
-*/
-    void cmodulus_int (INTVAL value, PMC* dest) {
-        VTABLE_set_integer_native(INTERP, dest,
-            PMC_int_val(SELF) % value);
-    }
+Calculates the value of corrected C<mod> C<value> and returns
+the result in C<dest>. See also ops/math.ops.
 
-/*
+=item C<void i_modulus(PMC *value)>
 
-=item C<void modulus(PMC *value, PMC *dest)>
+=item C<void i_modulus(INTVAL value)>
 
-Calculates the value of the integer C<mod> C<*value> and returns the
-result in C<*dest>.
+=item C<void i_modulus(FLOATVAL value)>
+
+Calculates modulus inplace
 
 =cut
 
 */
-    void modulus (PMC* value, PMC* dest) {
+
+    PMC* modulus (PMC* value, PMC* dest) {
+MMD_BigInt: {
+            return overflow_p(INTERP, SELF, value, dest, MMD_MOD);
+        }
+MMD_DEFAULT: {
+            INTVAL d = VTABLE_get_integer(INTERP, value);
+
+            if (d == 0)
+                real_exception(INTERP, NULL, E_ZeroDivisionError,
+                        "int modulus by zero");
+            if (!dest)
+                dest = pmc_new(INTERP, SELF->vtable->base_type);
+            VTABLE_set_integer_native(INTERP, dest,
+                    intval_mod(DYNSELF.get_integer(), d));
+            return dest;
+        }
+    }
+
+    PMC* modulus_int (INTVAL value, PMC* dest) {
+        if (value == 0)
+            real_exception(INTERP, NULL, E_ZeroDivisionError,
+                    "int modulus by zero");
+        if (!dest)
+            dest = pmc_new(INTERP, SELF->vtable->base_type);
+        VTABLE_set_integer_native(INTERP, dest,
+                intval_mod(DYNSELF.get_integer(), value));
+        return dest;
+    }
+
+    PMC* modulus_float (FLOATVAL value, PMC* dest) {
+        if (value == 0.0)
+            real_exception(INTERP, NULL, E_ZeroDivisionError,
+                    "int modulus by zero");
+        if (!dest)
+            dest = pmc_new(INTERP, SELF->vtable->base_type);
         VTABLE_set_integer_native(INTERP, dest,
-            intval_mod(PMC_int_val(SELF),
-            VTABLE_get_integer(INTERP, value)));
+                intval_mod(DYNSELF.get_integer(), value));
+        return dest;
+    }
+    void i_modulus (PMC* value) {
+MMD_BigInt: {
+             overflow_p(INTERP, SELF, value, SELF, MMD_MOD);
+        }
+MMD_DEFAULT: {
+            INTVAL d = VTABLE_get_integer(INTERP, value);
+
+            if (d == 0.0)
+                real_exception(INTERP, NULL, E_ZeroDivisionError,
+                        "int modulus by zero");
+            VTABLE_set_integer_native(INTERP, SELF,
+                    intval_mod(DYNSELF.get_integer() , d));
+        }
+    }
+
+    void i_modulus_int (INTVAL value) {
+        if (value == 0)
+            real_exception(INTERP, NULL, E_ZeroDivisionError,
+                    "int modulus by zero");
+        VTABLE_set_integer_native(INTERP, SELF,
+                intval_mod(DYNSELF.get_integer() , value));
+    }
+
+    void i_modulus_float (FLOATVAL value) {
+        if (value == 0.0)
+            real_exception(INTERP, NULL, E_ZeroDivisionError,
+                    "int modulus by zero");
+        VTABLE_set_integer_native(INTERP, SELF,
+                intval_mod(DYNSELF.get_integer() , value));
     }
 
 /*
 
-=item C<void modulus_int(INTVAL value, PMC *dest)>
+=item C<PMC* pow(PMC* value, PMC *dest)>
 
-Calculates the value of the integer C<mod> C<value> and returns the
-result in C<*dest>.
+=item C<PMC* pow_int(INTVAL value, PMC *dest)>
+
+Return SELF to the C<value>th power and return result in C<dest>.
+
+=item C<void i_pow(PMC* value)>
+
+=item C<void i_pow_int(INTVAL value)>
+
+Rise SELF to the C<value>th power.
+
+TODO Complex and BigInt rhs.
 
 =cut
 
 */
-    void modulus_int (INTVAL value, PMC* dest) {
-        VTABLE_set_integer_native(INTERP, dest,
-            intval_mod(PMC_int_val(SELF), value));
+    PMC* pow (PMC* value, PMC* dest) {
+        INTVAL v = VTABLE_get_integer(INTERP, value);
+        return SELF.pow_int(v, dest);
+    }
+
+    PMC* pow_int (INTVAL b, PMC* dest) {
+        INTVAL a = DYNSELF.get_integer();
+        INTVAL prev, temp, r;
+
+        if (b < 0)
+            return SUPER(b, dest);
+        r = 1;
+        if (a) {
+            temp = a;
+            while (b > 0) {
+                prev = r;
+                if (b & 1) {
+                    r *= temp;
+                    if (r / temp != prev) {
+                        return overflow(INTERP, SELF, b, dest, MMD_POW);
+                    }
+                }
+                b >>= 1;
+                if (!b)
+                    break;
+                prev = temp;
+                temp *= temp;
+               if (prev != 0 && temp / prev != prev) {
+                    return overflow(INTERP, SELF, b, dest, MMD_POW);
+                }
+            }
+        }
+        if (!dest)
+            dest = pmc_new(INTERP, SELF->vtable->base_type);
+        VTABLE_set_integer_native(INTERP, dest, r);
+        return dest;
+
+    }
+
+    void i_pow(PMC* value) {
+        SELF.pow(value, SELF);
+    }
+
+    void i_pow_int(INTVAL value) {
+        SELF.pow_int(value, SELF);
     }
 
+
 /*
 
 =item C<void neg(PMC *dest)>

Modified: trunk/classes/perlstring.pmc
==============================================================================
--- trunk/classes/perlstring.pmc        (original)
+++ trunk/classes/perlstring.pmc        Sun Apr 17 08:16:41 2005
@@ -113,32 +113,6 @@
 
 /*
 
-=item C<void modulus(PMC *value, PMC *dest)>
-
-Calculates the string C<mod> C<*value> and returns the result in
-C<*dest>.
-
-When Python mode is enabled does sprintf :(
-
-=cut
-
-*/
-
-    void modulus (PMC* value, PMC* dest) {
-        if (value->vtable == Parrot_base_vtables[enum_class_PerlInt]) {
-            VTABLE_set_integer_native(INTERP, dest,
-                    VTABLE_get_integer(INTERP, SELF) %
-                    PMC_int_val(value)
-                    );
-        }
-        else {
-            internal_exception(INVALID_OPERATION,
-                    "modulus() not implemented for PerlString");
-        }
-    }
-
-/*
-
 =item C<void increment()>
 
 =item C<void decrement()>

Modified: trunk/classes/perlundef.pmc
==============================================================================
--- trunk/classes/perlundef.pmc (original)
+++ trunk/classes/perlundef.pmc Sun Apr 17 08:16:41 2005
@@ -339,63 +339,45 @@
 
 /*
 
-=item C<void modulus(PMC *value, PMC *dest)>
+=item C<PMC* modulus(PMC *value, PMC *dest)>
 
 =cut
 
 */
 
-    void modulus (PMC* value,  PMC* dest) {
+    PMC* modulus (PMC* value,  PMC* dest) {
         Parrot_warn(INTERP, PARROT_WARNINGS_UNDEF_FLAG,
-        "Use of uninitialized value in modulus");
-        if(value->vtable == Parrot_base_vtables[enum_class_PerlUndef]) {
-            internal_exception(DIV_BY_ZERO, "division by zero!");
-        }
-        else if(value->vtable == Parrot_base_vtables[enum_class_PerlInt]) {
-            if(VTABLE_get_integer(INTERP, value) == 0) {
-                internal_exception(DIV_BY_ZERO, "division by zero!");
-            }
-        }
-        else if(VTABLE_get_number(INTERP, value) == 0) {
-            internal_exception(DIV_BY_ZERO, "division by zero!");
-        }
-
-        VTABLE_set_integer_native(INTERP, dest, 0);
+            "Use of uninitialized value in modulus");
+        return SUPER(value, dest);
     }
 
 /*
 
-=item C<void modulus_int(INTVAL value, PMC *dest)>
+=item C<PMC* modulus_int(INTVAL value, PMC *dest)>
 
 =cut
 
 */
 
-    void modulus_int (INTVAL value,  PMC* dest) {
+    PMC* modulus_int (INTVAL value,  PMC* dest) {
         Parrot_warn(INTERP, PARROT_WARNINGS_UNDEF_FLAG,
-        "Use of uninitialized value in integer modulus");
-        if(value == 0) {
-            internal_exception(DIV_BY_ZERO, "division by zero!");
-        }
-        VTABLE_set_integer_native(INTERP, dest, 0);
+            "Use of uninitialized value in integer modulus");
+        return SUPER(value, dest);
     }
 
 
 /*
 
-=item C<void modulus_float(FLOATVAL value, PMC *dest)>
+=item C<PMC* modulus_float(FLOATVAL value, PMC *dest)>
 
 =cut
 
 */
 
-    void modulus_float (FLOATVAL value,  PMC* dest) {
+    PMC* modulus_float (FLOATVAL value,  PMC* dest) {
         Parrot_warn(INTERP, PARROT_WARNINGS_UNDEF_FLAG,
-        "Use of uninitialized value in numeric modulus");
-        if(value == 0) {
-            internal_exception(DIV_BY_ZERO, "division by zero!");
-        }
-        VTABLE_set_integer_native(INTERP, dest, 0);
+            "Use of uninitialized value in numeric modulus");
+        return SUPER(value, dest);
     }
 
 /*

Modified: trunk/classes/scalar.pmc
==============================================================================
--- trunk/classes/scalar.pmc    (original)
+++ trunk/classes/scalar.pmc    Sun Apr 17 08:16:41 2005
@@ -454,61 +454,238 @@
     }
 
 
+/*
 
+=item C<PMC* cmodulus(PMC *value, PMC *dest)>
 
-/*
+=item C<PMC* cmodulus(INTVAL value, PMC *dest)>
+
+=item C<PMC* cmodulus(FLOATVAL value, PMC *dest)>
 
-=item C<void modulus(PMC* value, PMC* dest)>
+Calculates the value of the number C-style C<mod> C<value> and returns
+the result in C<dest>.
 
-This does perl-like modulus.
+=item C<void i_cmodulus(PMC *value)>
 
-Returns in C<*dest> the value of the scalar C<mod> the integer value of
-C<*value>.
+=item C<void i_cmodulus(INTVAL value)>
+
+=item C<void i_cmodulus(FLOATVAL value)>
+
+Calculates the value of the number C-style C<mod> C<value> and returns
+the result in C<dest>.
 
 =cut
 
 */
 
-    void modulus (PMC* value,  PMC* dest) {
-        INTVAL result;
+    PMC* cmodulus (PMC* value, PMC* dest) {
+        FLOATVAL d = VTABLE_get_number(INTERP, value);
+
+        if (d == 0.0)
+            real_exception(INTERP, NULL, E_ZeroDivisionError,
+                    "float cmodulus by zero");
+        if (!dest)
+            dest = pmc_new(INTERP, SELF->vtable->base_type);
+        VTABLE_set_number_native(INTERP, dest,
+                fmod(DYNSELF.get_number(), d));
+        return dest;
+    }
+
+    PMC* cmodulus_float (FLOATVAL value, PMC* dest) {
+        if (value == 0.0)
+            real_exception(INTERP, NULL, E_ZeroDivisionError,
+                    "float cmodulus by zero");
+        if (!dest)
+            dest = pmc_new(INTERP, SELF->vtable->base_type);
+        VTABLE_set_number_native(INTERP, dest,
+                fmod(DYNSELF.get_number(), value));
+        return dest;
+    }
+
+    PMC* cmodulus_float (FLOATVAL value, PMC* dest) {
+        if (value == 0)
+            real_exception(INTERP, NULL, E_ZeroDivisionError,
+                    "float cmodulus by zero");
+        if (!dest)
+            dest = pmc_new(INTERP, SELF->vtable->base_type);
+        VTABLE_set_number_native(INTERP, dest,
+                fmod(DYNSELF.get_number(), value));
+        return dest;
+    }
+    void i_cmodulus (PMC* value) {
+        FLOATVAL d = VTABLE_get_number(INTERP, value);
+
+        if (d == 0.0)
+            real_exception(INTERP, NULL, E_ZeroDivisionError,
+                    "float cmodulus by zero");
+        VTABLE_set_number_native(INTERP, SELF,
+                fmod(DYNSELF.get_number() , d));
+    }
 
-        result = DYNSELF.get_integer()
-            % VTABLE_get_integer(INTERP, value);
+    void i_cmodulus_int (INTVAL value) {
+        if (value == 0)
+            real_exception(INTERP, NULL, E_ZeroDivisionError,
+                    "float cmodulus by zero");
+        VTABLE_set_number_native(INTERP, SELF,
+                fmod(DYNSELF.get_number() , value));
+    }
 
-        VTABLE_set_integer_native(INTERP, dest, result);
+    void i_cmodulus_float (FLOATVAL value) {
+        if (value == 0.0)
+            real_exception(INTERP, NULL, E_ZeroDivisionError,
+                    "float cmodulus by zero");
+        VTABLE_set_number_native(INTERP, SELF,
+                fmod(DYNSELF.get_number() , value));
     }
 
 /*
 
-=item C<void modulus_int(INTVAL value, PMC* dest)>
+=item C<PMC* modulus(PMC *value, PMC *dest)>
+
+=item C<PMC* modulus(INTVAL value, PMC *dest)>
+
+=item C<PMC* modulus(FLOATVAL value, PMC *dest)>
+
+Calculates the value of corrected C<mod> C<value> and returns
+the result in C<dest>. See also ops/math.ops.
+
+=item C<void i_modulus(PMC *value)>
 
-Returns in C<*dest> the value of the scalar C<mod> C<value>.
+=item C<void i_modulus(INTVAL value)>
+
+=item C<void i_modulus(FLOATVAL value)>
+
+Calculates modulus inplace
 
 =cut
 
 */
 
-    void modulus_int (INTVAL value,  PMC* dest) {
-        INTVAL result;
+    PMC* modulus (PMC* value, PMC* dest) {
+        FLOATVAL d = VTABLE_get_number(INTERP, value);
+
+        if (d == 0.0)
+            real_exception(INTERP, NULL, E_ZeroDivisionError,
+                    "float modulus by zero");
+        if (!dest)
+            dest = pmc_new(INTERP, SELF->vtable->base_type);
+        VTABLE_set_number_native(INTERP, dest,
+                floatval_mod(DYNSELF.get_number(), d));
+        return dest;
+    }
+
+    PMC* modulus_int (INTVAL value, PMC* dest) {
+        if (value == 0)
+            real_exception(INTERP, NULL, E_ZeroDivisionError,
+                    "float modulus by zero");
+        if (!dest)
+            dest = pmc_new(INTERP, SELF->vtable->base_type);
+        VTABLE_set_number_native(INTERP, dest,
+                floatval_mod(DYNSELF.get_number(), value));
+        return dest;
+    }
+
+    PMC* modulus_float (FLOATVAL value, PMC* dest) {
+        if (value == 0.0)
+            real_exception(INTERP, NULL, E_ZeroDivisionError,
+                    "float modulus by zero");
+        if (!dest)
+            dest = pmc_new(INTERP, SELF->vtable->base_type);
+        VTABLE_set_number_native(INTERP, dest,
+                floatval_mod(DYNSELF.get_number(), value));
+        return dest;
+    }
+
+    void i_modulus (PMC* value) {
+        FLOATVAL d = VTABLE_get_number(INTERP, value);
 
-        result = DYNSELF.get_integer()
-            % value;
+        if (d == 0.0)
+            real_exception(INTERP, NULL, E_ZeroDivisionError,
+                    "float modulus by zero");
+        VTABLE_set_number_native(INTERP, SELF,
+                floatval_mod(DYNSELF.get_number() , d));
+    }
+
+    void i_modulus_int (INTVAL value) {
+        if (value == 0)
+            real_exception(INTERP, NULL, E_ZeroDivisionError,
+                    "float modulus by zero");
+        VTABLE_set_number_native(INTERP, SELF,
+                floatval_mod(DYNSELF.get_number() , value));
+    }
 
-        VTABLE_set_integer_native(INTERP, dest, result);
+    void i_modulus_float (FLOATVAL value) {
+        if (value == 0.0)
+            real_exception(INTERP, NULL, E_ZeroDivisionError,
+                    "float modulus by zero");
+        VTABLE_set_number_native(INTERP, SELF,
+                floatval_mod(DYNSELF.get_number() , value));
     }
 
 /*
 
-=item C<void modulus_float(FLOATVAL value, PMC *dest)>
+=item C<PMC* pow(PMC *value, PMC *dest)>
+
+=item C<PMC* pow_int(INTVAL value, PMC *dest)>
+
+=item C<PMC* pow_float(FLOATVAL value, PMC *dest)>
+
+Calculates  C<SELF pow value> and returns
+the result in C<dest>. See also ops/math.ops.
+
+=item C<void i_pow(PMC *value)>
+
+=item C<void i_pow_int(INTVAL value)>
+
+=item C<void i_pow_float(FLOATVAL value)>
 
-Calls the superclass implementation.
+Calculates pow inplace
 
 =cut
 
 */
 
-    void modulus_float (FLOATVAL value,  PMC* dest) {
-        SUPER(value, dest);
+    PMC* pow (PMC* value, PMC* dest) {
+        FLOATVAL d = VTABLE_get_number(INTERP, value);
+
+        if (!dest)
+            dest = pmc_new(INTERP, SELF->vtable->base_type);
+        VTABLE_set_number_native(INTERP, dest,
+                pow(DYNSELF.get_number(), d));
+        return dest;
+    }
+
+    PMC* pow_int (INTVAL value, PMC* dest) {
+        if (!dest)
+            dest = pmc_new(INTERP, SELF->vtable->base_type);
+        VTABLE_set_number_native(INTERP, dest,
+                pow(DYNSELF.get_number(), value));
+        return dest;
+    }
+
+    PMC* pow_float (FLOATVAL value, PMC* dest) {
+        if (!dest)
+            dest = pmc_new(INTERP, SELF->vtable->base_type);
+        VTABLE_set_number_native(INTERP, dest,
+                pow(DYNSELF.get_number(), value));
+        return dest;
+    }
+
+    void i_pow (PMC* value) {
+        FLOATVAL d = VTABLE_get_number(INTERP, value);
+
+        VTABLE_set_number_native(INTERP, SELF,
+                pow(DYNSELF.get_number(), d));
+    }
+
+    void i_pow_int (INTVAL value) {
+        VTABLE_set_number_native(INTERP, SELF,
+                pow(DYNSELF.get_number(), value));
+    }
+
+    void i_pow_float (FLOATVAL value) {
+        VTABLE_set_number_native(INTERP, SELF,
+                pow(DYNSELF.get_number(), value));
     }
 
 /*
@@ -522,7 +699,7 @@
 */
 
     void neg (PMC* dest) {
-        VTABLE_set_integer_native(INTERP, dest, -DYNSELF.get_integer());
+        VTABLE_set_number_native(INTERP, dest, -DYNSELF.get_number());
     }
 
 /*

Modified: trunk/dynclasses/pyfloat.pmc
==============================================================================
--- trunk/dynclasses/pyfloat.pmc        (original)
+++ trunk/dynclasses/pyfloat.pmc        Sun Apr 17 08:16:41 2005
@@ -163,18 +163,6 @@
         return VTABLE_get_integer(INTERP, SELF);
     }
 
-/*
-
-=item C<void modulus_float(FLOATVAL value, PMC *dest)>
-
-=cut
-
-*/
-
-    void modulus_float (FLOATVAL value, PMC* dest) {
-        VTABLE_set_number_native(INTERP, dest,
-            floatval_mod(PMC_num_val(SELF), value));
-    }
 
 /*
 

Modified: trunk/dynclasses/pyint.pmc
==============================================================================
--- trunk/dynclasses/pyint.pmc  (original)
+++ trunk/dynclasses/pyint.pmc  Sun Apr 17 08:16:41 2005
@@ -628,53 +628,6 @@
         VTABLE_set_integer_native(INTERP, value, !PMC_int_val(SELF));
     }
 
-/*
-
-=item C<void modulus(PMC *value, PMC *dest)>
-
-Calculates the value of the integer C-style C<mod> C<*value> and returns
-the result in C<*dest>.
-
-=cut
-
-*/
-
-    void modulus (PMC* value, PMC* dest) {
-MMD_PyInt: {
-            INTVAL pmci = PMC_int_val(SELF);
-            INTVAL vali = VTABLE_get_integer(INTERP, value);
-            INTVAL xdivy = pmci / vali;
-            INTVAL xmody = pmci - xdivy * vali;
-            if (xmody && ((vali ^ xmody) < 0) /* i.e. and signs differ */) {
-                xmody += vali;
-            }
-            VTABLE_set_integer_native(INTERP, dest, xmody);
-        }
-MMD_PyLong: {
-            promote(INTERP, SELF, value, dest, MMD_MOD);
-        }
-    }
-
-/*
-
-=item C<void modulus_int(INTVAL value, PMC *dest) >
-
-Calculates the value of the integer C-style C<mod> C<value> and returns
-the result in C<*dest>.
-
-=cut
-
-*/
-
-    void modulus_int (INTVAL value, PMC* dest) {
-        INTVAL pmci = PMC_int_val(SELF);
-        INTVAL xdivy = pmci / value;
-        INTVAL xmody = pmci - xdivy * value;
-        if (xmody && ((value ^ xmody) < 0) /* i.e. and signs differ */) {
-            xmody += value;
-        }
-        VTABLE_set_integer_native(INTERP, dest, xmody);
-    }
 
 
 /*
@@ -695,68 +648,6 @@
     }
 
 /*
-
-=item C<PMC* pow(PMC *value, PMC *dest)>
-
-Raises C<SELF> to the power of C<*value> and returns the result.
-
-=cut
-
-*/
-
-    void pow (PMC *value, PMC *dest) {
-MMD_PyInt: {
-            INTVAL vali = VTABLE_get_integer(INTERP, value);
-            mmd_dispatch_v_pip(INTERP, SELF, vali, dest, MMD_POW);
-        }
-MMD_PyFloat: {
-            FLOATVAL valf = VTABLE_get_number(INTERP, value);
-            mmd_dispatch_v_pnp(INTERP, SELF, valf, dest, MMD_POW);
-        }
-    }
-
-/*
-
-=item C<PMC* pow_float(FLOATVAL value, PMC *dest)>
-
-Raises C<SELF> to the power of C<*value> and returns the result.
-
-=cut
-
-*/
-
-    void pow_float (FLOATVAL value, PMC *dest) {
-        FLOATVAL pmcf = VTABLE_get_number(INTERP, SELF);
-        VTABLE_morph(INTERP, dest, PyBuiltin_PyFloat);
-        VTABLE_set_number_native(INTERP, dest, (FLOATVAL) pow(pmcf, value) );
-    }
-
-/*
-
-=item C<PMC* pow_int(INTVAL *value, PMC *dest)>
-
-Raises C<SELF> to the power of C<*value> and returns the result.
-
-=cut
-
-*/
-
-    void pow_int (INTVAL value, PMC *dest) {
-        if (value < 0)
-            mmd_dispatch_v_pnp(INTERP, SELF,
-                (FLOATVAL)value, dest, MMD_POW);
-        else {
-            int i;
-            INTVAL pmci = PMC_int_val(SELF);
-            VTABLE_morph(INTERP, dest, PyBuiltin_PyInt);
-            PMC_int_val(dest) = 1;
-            for (i=1; i<=value; i++) {
-                mmd_dispatch_v_pip(INTERP, dest, pmci, dest, MMD_MULTIPLY);
-            }
-        }
-    }
-
-/*
 
 =item C<void set_integer_native(INTVAL value)>
 

Modified: trunk/dynclasses/pystring.pmc
==============================================================================
--- trunk/dynclasses/pystring.pmc       (original)
+++ trunk/dynclasses/pystring.pmc       Sun Apr 17 08:16:41 2005
@@ -568,7 +568,7 @@
 
 /*
 
-=item C<void modulus(PMC *value, PMC *dest)>
+=item C<PMC* modulus(PMC *value, PMC *dest)>
 
 Interpolates a formatstring with a set of values.
 
@@ -576,7 +576,7 @@
 
 */
 
-    void modulus (PMC* value, PMC* dest) {
+    PMC* modulus (PMC* value, PMC* dest) {
         PMC *ar = value;
         /*
          * SELF is formatstring, value = argument array or item
@@ -588,8 +588,11 @@
             VTABLE_set_integer_native(INTERP, ar, 1);
             VTABLE_set_pmc_keyed_int( INTERP, ar, 0, value);
         }
+        if (!dest)
+            dest = pmc_new(INTERP, PyBuiltin_PyString);
         VTABLE_set_string_native(INTERP, dest,
                 Parrot_psprintf(INTERP, PMC_str_val(SELF), ar));
+        return dest;
     }
 
 /*

Modified: trunk/imcc/parser_util.c
==============================================================================
--- trunk/imcc/parser_util.c    (original)
+++ trunk/imcc/parser_util.c    Sun Apr 17 08:16:41 2005
@@ -371,6 +371,12 @@
         return MMD_DIVIDE;
     if (strcmp(name, "fdiv") == 0)
         return MMD_FLOOR_DIVIDE;
+    if (strcmp(name, "mod") == 0)
+        return MMD_MOD;
+    if (strcmp(name, "cmod") == 0)
+        return MMD_CMOD;
+    if (strcmp(name, "pow") == 0)
+        return MMD_POW;
     return -1;
 }
 

Modified: trunk/vtable.tbl
==============================================================================
--- trunk/vtable.tbl    (original)
+++ trunk/vtable.tbl    Sun Apr 17 08:16:41 2005
@@ -179,17 +179,29 @@
 void i_floor_divide_int(INTVAL value)        MMD_I_FLOOR_DIVIDE_INT
 void i_floor_divide_float(FLOATVAL value)    MMD_I_FLOOR_DIVIDE_FLOAT
 
-void modulus(PMC* value, PMC* dest)         MMD_MOD
-void modulus_int(INTVAL value, PMC* dest)   MMD_MOD_INT
-void modulus_float(FLOATVAL value, PMC* dest) MMD_MOD_FLOAT
-
-void cmodulus(PMC* value, PMC* dest)        MMD_CMOD
-void cmodulus_int(INTVAL value, PMC* dest)  MMD_CMOD_INT
-void cmodulus_float(FLOATVAL value, PMC* dest) MMD_CMOD_FLOAT
-
-void pow(PMC* value, PMC* dest)        MMD_POW
-void pow_int(INTVAL value, PMC* dest) MMD_POW_INT
-void pow_float(FLOATVAL value, PMC* dest) MMD_POW_FLOAT
+PMC* modulus(PMC* value, PMC* dest)         MMD_MOD
+PMC* modulus_int(INTVAL value, PMC* dest)   MMD_MOD_INT
+PMC* modulus_float(FLOATVAL value, PMC* dest) MMD_MOD_FLOAT
+
+void i_modulus(PMC* value)                  MMD_I_MOD
+void i_modulus_int(INTVAL value)            MMD_I_MOD_INT
+void i_modulus_float(FLOATVAL value)        MMD_I_MOD_FLOAT
+
+PMC* cmodulus(PMC* value, PMC* dest)        MMD_CMOD
+PMC* cmodulus_int(INTVAL value, PMC* dest)  MMD_CMOD_INT
+PMC* cmodulus_float(FLOATVAL value, PMC* dest) MMD_CMOD_FLOAT
+
+void i_cmodulus(PMC* value)                 MMD_I_CMOD
+void i_cmodulus_int(INTVAL value)           MMD_I_CMOD_INT
+void i_cmodulus_float(FLOATVAL value)       MMD_I_CMOD_FLOAT
+
+PMC* pow(PMC* value, PMC* dest)             MMD_POW
+PMC* pow_int(INTVAL value, PMC* dest)       MMD_POW_INT
+PMC* pow_float(FLOATVAL value, PMC* dest)   MMD_POW_FLOAT
+
+void i_pow(PMC* value)                      MMD_I_POW
+void i_pow_int(INTVAL value)                MMD_I_POW_INT
+void i_pow_float(FLOATVAL value)            MMD_I_POW_FLOAT
 
 void increment()
 void decrement()

Reply via email to