Author: leo
Date: Fri Apr 22 00:56:21 2005
New Revision: 7903

Modified:
   trunk/classes/boolean.pmc
   trunk/classes/float.pmc
   trunk/classes/integer.pmc
   trunk/classes/perlint.pmc
   trunk/classes/perlnum.pmc
   trunk/classes/perlscalar.pmc
   trunk/classes/perlstring.pmc
   trunk/classes/perlundef.pmc
   trunk/classes/scalar.pmc
   trunk/classes/string.pmc
   trunk/dynclasses/pyobject.pmc
   trunk/imcc/parser_util.c
   trunk/t/pmc/objects.t
   trunk/vtable.tbl
Log:
MMD 33 - convert logical or, and, xor

* see also note on p6i: [RFC] assign Px, Py
* use one assign_pmc in scalar.pmc

* fix multiply bug reported by Cory


Modified: trunk/classes/boolean.pmc
==============================================================================
--- trunk/classes/boolean.pmc   (original)
+++ trunk/classes/boolean.pmc   Fri Apr 22 00:56:21 2005
@@ -103,9 +103,6 @@
         PMC_int_val(SELF) = (value != 0);
     }
 
-    void set_pmc (PMC* value) {
-        PMC_int_val(SELF) = VTABLE_get_bool(INTERP, value);
-    }
 /*
 
 =item C<void set_number_native (FLOATVAL value)>

Modified: trunk/classes/float.pmc
==============================================================================
--- trunk/classes/float.pmc     (original)
+++ trunk/classes/float.pmc     Fri Apr 22 00:56:21 2005
@@ -128,6 +128,8 @@
 
 =item C<void set_integer_native(INTVAL value)>
 
+=item C<void set_bool(INTVAL value)>
+
 =cut
 
 */
@@ -137,6 +139,11 @@
         DYNSELF.set_integer_native(value);
     }
 
+    void set_bool (INTVAL value) {
+        DYNSELF.morph(enum_class_Boolean);
+        DYNSELF.set_bool(value);
+    }
+
 /*
 
 =item C<void set_number_native(FLOATVAL value)>

Modified: trunk/classes/integer.pmc
==============================================================================
--- trunk/classes/integer.pmc   (original)
+++ trunk/classes/integer.pmc   Fri Apr 22 00:56:21 2005
@@ -32,7 +32,7 @@
 overflow(Interp *interpreter, PMC *self, INTVAL b, PMC *dest, int mmd)
 {
     PMC *temp;
-    INTVAL a = PMC_int_val(self);
+    INTVAL a = VTABLE_get_integer(interpreter, self);
 
     if (PARROT_ERRORS_test(interpreter,PARROT_ERRORS_OVERFLOW_FLAG)) {
         real_exception(interpreter, NULL, ERR_OVERFLOW,
@@ -54,7 +54,7 @@
 overflow_p(Interp *interpreter, PMC *self, PMC *val, PMC *dest, int mmd)
 {
     PMC *temp;
-    INTVAL a = PMC_int_val(self);
+    INTVAL a = VTABLE_get_integer(interpreter, self);
 
     if (PARROT_ERRORS_test(interpreter,PARROT_ERRORS_OVERFLOW_FLAG)) {
         real_exception(interpreter, NULL, ERR_OVERFLOW,
@@ -248,71 +248,6 @@
 
 /*
 
-=item C<void morph(INTVAL type)>
-
-Morphs the scalar to the specified type.
-
-=cut
-
-*/
-
-    void morph (INTVAL type) {
-        if (SELF->vtable->base_type == type)
-            return;
-        if (type == enum_class_String) {
-            /*
-             * if we morph to a string, first clear str_val
-             * so that after changing the vtable a parallel
-             * reader doesn't get a garbage pointer
-             */
-            PMC_str_val(SELF) = NULL;
-            PObj_custom_mark_SET(SELF);
-            SELF->vtable = Parrot_base_vtables[type];
-            return;
-        }
-        if (type == enum_class_BigInt || type == enum_class_Complex) {
-            PMC_str_val(SELF) = NULL;
-            SELF->vtable = Parrot_base_vtables[type];
-            DYNSELF.init();
-            return;
-        }
-        SELF->vtable = Parrot_base_vtables[type];
-    }
-/*
-
-=item C<void assign_pmc(PMC *value)>
-
-Sets the PMC C<*value>, calling the appropriate C<set_*> method
-according to the type of C<*value>.
-
-=cut
-
-*/
-
-    void assign_pmc (PMC* value) {
-        if (SELF == value)
-            return;
-        DYNSELF.morph(value->vtable->base_type);
-        switch (value->vtable->base_type) {
-            case enum_class_Integer:
-                DYNSELF.set_integer_same(value);
-                break;
-            case enum_class_Float:
-                DYNSELF.set_number_same(value);
-                break;
-            case enum_class_String:
-                DYNSELF.set_string_same(value);
-                break;
-            case enum_class_PerlUndef:
-                (void) VTABLE_get_pmc(INTERP, value);
-                break;
-            default:
-                SUPER(value);
-                break;
-        }
-    }
-/*
-
 =item C<void set_integer_same(PMC *value)>
 
 =item C<void set_integer_native(INTVAL value)>
@@ -668,7 +603,7 @@
     }
 
     PMC* multiply_int (INTVAL b, PMC* dest) {
-        INTVAL a = PMC_int_val(SELF);
+        INTVAL a = DYNSELF.get_integer();
         double cf = (double)a * (double)b;
         INTVAL c = a * b;
         if ((double) c == cf) {
@@ -713,7 +648,7 @@
     }
 
     void i_multiply_int (INTVAL b) {
-        INTVAL a = PMC_int_val(SELF);
+        INTVAL a = DYNSELF.get_integer();
         double cf = (double)a * (double)b;
         INTVAL c = a * b;
         if ((double) c == cf) {
@@ -1252,20 +1187,6 @@
     }
 
 /*
-
-=item C<void logical_not(PMC *value)>
-
-Calculates the logical negation of the integer and returns the result in
-C<*value>.
-
-=cut
-
-*/
-    void logical_not (PMC* value) {
-        VTABLE_set_integer_native(INTERP, value, !PMC_int_val(SELF));
-    }
-
-/*
 
 =item C<void increment()>
 

Modified: trunk/classes/perlint.pmc
==============================================================================
--- trunk/classes/perlint.pmc   (original)
+++ trunk/classes/perlint.pmc   Fri Apr 22 00:56:21 2005
@@ -21,25 +21,10 @@
 #include "parrot/parrot.h"
 
 void Parrot_perlscalar_morph(Interp* , PMC* pmc, INTVAL type);
-void Parrot_perlscalar_set_pmc(Interp* , PMC* pmc, PMC* value);
 
 /* TODO extends PerlAny or perlscalar or whatever */
 pmclass PerlInt extends Integer {
 
-/*
-
-=item C<void set_pmc(PMC *value)>
-
-Sets the value of the number to the value in C<*value>.
-
-=cut
-
-*/
-
-
-    void set_pmc (PMC* value) {
-        perlscalar.SELF.set_pmc(value);
-    }
 
 /*
 

Modified: trunk/classes/perlnum.pmc
==============================================================================
--- trunk/classes/perlnum.pmc   (original)
+++ trunk/classes/perlnum.pmc   Fri Apr 22 00:56:21 2005
@@ -21,7 +21,6 @@
 #include "parrot/parrot.h"
 
 void Parrot_perlscalar_morph(Interp* , PMC* pmc, INTVAL type);
-void Parrot_perlscalar_set_pmc(Interp* , PMC* pmc, PMC* value);
 
 pmclass PerlNum extends Float {
 
@@ -44,19 +43,6 @@
         return Parrot_sprintf_c(INTERP, "%s" FLOATVAL_FMT, sign, d);
     }
 
-/*
-
-=item C<void set_pmc(PMC *value)>
-
-Sets the value of the number to the value in C<*value>.
-
-=cut
-
-*/
-
-    void set_pmc (PMC* value) {
-        perlscalar.SELF.set_pmc(value);
-    }
 
 /*
 

Modified: trunk/classes/perlscalar.pmc
==============================================================================
--- trunk/classes/perlscalar.pmc        (original)
+++ trunk/classes/perlscalar.pmc        Fri Apr 22 00:56:21 2005
@@ -39,62 +39,14 @@
     void morph (INTVAL type) {
         if (SELF->vtable->base_type == type)
             return;
-        if (SELF->vtable->base_type == enum_class_PerlString) {
-            PObj_custom_mark_CLEAR(SELF);
-            SELF->vtable = Parrot_base_vtables[type];
-            return;
-        }
-        if (type == enum_class_PerlString) {
-            /*
-             * if we morph to a string, first clear str_val
-             * so that after changing the vtable a parallel
-             * reader doesn't get a garbage pointer
-             */
-            PMC_str_val(SELF) = NULL;
-            PObj_custom_mark_SET(SELF);
-            SELF->vtable = Parrot_base_vtables[type];
-            return;
-        }
-        if (type == enum_class_BigInt || type == enum_class_Complex) {
-            PMC_str_val(SELF) = NULL;
-            SELF->vtable = Parrot_base_vtables[type];
-            DYNSELF.init();
-            return;
-        }
-        SELF->vtable = Parrot_base_vtables[type];
-    }
-
-/*
-
-=item C<void set_pmc(PMC *value)>
-
-Sets the PMC C<*value>, calling the appropriate C<set_*> method
-according to the type of C<*value>.
-
-=cut
-
-*/
-
-    void set_pmc (PMC* value) {
-        DYNSELF.morph(value->vtable->base_type);
-        switch (value->vtable->base_type) {
-            case enum_class_Boolean:
-            case enum_class_PerlInt:
-                DYNSELF.set_integer_same(value);
-                break;
-            case enum_class_PerlNum:
-                DYNSELF.set_number_same(value);
-                break;
-            case enum_class_PerlString:
-                DYNSELF.set_string_same(value);
-                break;
-            case enum_class_PerlUndef:
-                (void) VTABLE_get_pmc(INTERP, value);
-                break;
-            default:
-                DYNSELF.set_pmc(value);
-                break;
+        switch (type) {
+            case enum_class_Integer: type = enum_class_PerlInt; break;
+            case enum_class_Float:   type = enum_class_PerlNum; break;
+            case enum_class_String:  type = enum_class_PerlString; break;
+            case enum_class_Undef:
+            case enum_class_None:    type = enum_class_PerlUndef; break;
         }
+        pmc_reuse(INTERP, SELF, type, 0);
     }
 
 }

Modified: trunk/classes/perlstring.pmc
==============================================================================
--- trunk/classes/perlstring.pmc        (original)
+++ trunk/classes/perlstring.pmc        Fri Apr 22 00:56:21 2005
@@ -9,7 +9,7 @@
 =head1 DESCRIPTION
 
 C<PerlString> extends C<String> to provide Perl-specific string behaviour.
-Note that the C<morph> and C<set_pmc> methods come from C<PerlScalar>,
+Note that the C<morph> method comes from C<PerlScalar>,
 not from C<String>.
 
 =head2 Methods
@@ -23,7 +23,6 @@
 #include "parrot/parrot.h"
 
 void Parrot_perlscalar_morph(Interp* , PMC* pmc, INTVAL type);
-void Parrot_perlscalar_set_pmc(Interp* , PMC* pmc, PMC* value);
 
 pmclass PerlString extends String {
 
@@ -82,21 +81,6 @@
         DYNSELF.set_number_native(value);
     }
 
-
-/*
-
-=item C<void set_pmc(PMC *value)>
-
-Sets the value of the PMC to the value in C<*value>.
-
-=cut
-
-*/
-
-    void set_pmc (PMC* value) {
-        perlscalar.SELF.set_pmc(value);
-    }
-
 /*
 
 =item C<void morph(INTVAL type)>

Modified: trunk/classes/perlundef.pmc
==============================================================================
--- trunk/classes/perlundef.pmc (original)
+++ trunk/classes/perlundef.pmc Fri Apr 22 00:56:21 2005
@@ -406,50 +406,92 @@
 
 /*
 
-=item C<void logical_or(PMC *value, PMC *dest)>
+=item C<PMC* logical_or(PMC *value, PMC *dest)>
+
+=item C<void i_logical_or(PMC *value)>
 
 =cut
 
 */
 
-    void logical_or (PMC* value,  PMC* dest) {
-        VTABLE_set_pmc(INTERP, dest, value);
+    PMC* logical_or (PMC* value,  PMC* dest) {
+        if (!dest)
+            return VTABLE_clone(INTERP, value);
+        VTABLE_assign_pmc(INTERP, dest, value);
+        return dest;
     }
 
+    void i_logical_or (PMC* value) {
+        VTABLE_assign_pmc(INTERP, SELF, value);
+    }
 /*
 
-=item C<void logical_and(PMC *value, PMC *dest)>
+=item C<PMC* logical_and(PMC *value, PMC *dest)>
+
+=item C<void i_logical_and(PMC *value)>
 
 =cut
 
 */
 
-    void logical_and (PMC* value,  PMC* dest) {
-        VTABLE_set_pmc(INTERP, dest, SELF);
+    PMC* logical_and (PMC* value,  PMC* dest) {
+        if (!dest)
+            return DYNSELF.clone();
+        VTABLE_assign_pmc(INTERP, dest, SELF);
+        return dest;
+    }
+
+    void i_logical_and (PMC* value) {
     }
 
 /*
 
-=item C<void logical_xor(PMC *value, PMC *dest)>
+=item C<PMC* logical_xor(PMC *value, PMC *dest)>
+
+=item C<void i_logical_xor(PMC *value, PMC *dest)>
 
 =cut
 
 */
 
-    void logical_xor (PMC* value,  PMC* dest) {
+    PMC* logical_xor (PMC* value,  PMC* dest) {
+MMD_PerlUndef: {
+            if (!dest)
+                dest = pmc_new(INTERP, SELF->vtable->base_type);
+            VTABLE_set_bool(INTERP, dest, 0);
+            return dest;
+        }
+MMD_DEFAULT: {
+
+            INTVAL value_bool = VTABLE_get_bool(INTERP, value);
+            if (value_bool) {
+                if (!dest)
+                    return VTABLE_clone(INTERP, value);
+                VTABLE_assign_pmc(INTERP, dest, value);
+                return dest;
+            }
+            else {
+                if (!dest)
+                    dest = pmc_new(INTERP, SELF->vtable->base_type);
+                VTABLE_set_bool(INTERP, dest, 0);
+            }
+            return dest;
+        }
+    }
+
+    void i_logical_xor (PMC* value) {
 MMD_PerlUndef: {
-            VTABLE_set_integer_native(INTERP, dest, 0);
+            VTABLE_set_bool(INTERP, SELF, 0);
         }
 MMD_DEFAULT: {
 
         INTVAL value_bool = VTABLE_get_bool(INTERP, value);
         if (value_bool)
-            VTABLE_set_pmc(INTERP, dest, value);
+            VTABLE_assign_pmc(INTERP, SELF, value);
         else
-            VTABLE_set_integer_native(INTERP, dest, 0);
+            VTABLE_set_bool(INTERP, SELF, 0);
         }
     }
-
 /*
 
 =item C<void logical_not(PMC *dest)>

Modified: trunk/classes/scalar.pmc
==============================================================================
--- trunk/classes/scalar.pmc    (original)
+++ trunk/classes/scalar.pmc    Fri Apr 22 00:56:21 2005
@@ -24,6 +24,64 @@
 
 /*
 
+=item C<void morph(INTVAL type)>
+
+Morphs the scalar to the specified type.
+
+=cut
+
+*/
+
+    void morph (INTVAL type) {
+        if (SELF->vtable->base_type == type)
+            return;
+        pmc_reuse(INTERP, SELF, type, 0);
+    }
+/*
+
+=item C<void assign_pmc(PMC *value)>
+
+Sets the PMC C<*value>, calling the appropriate C<set_*> method
+according to the type of C<*value>.
+
+=cut
+
+*/
+
+    void assign_pmc (PMC* value) {
+        STRING *s_int = CONST_STRING(INTERP, "Integer");
+        STRING *s_num = CONST_STRING(INTERP, "Float");
+        STRING *s_str = CONST_STRING(INTERP, "String");
+        if (SELF->vtable->base_type == enum_class_Boolean) {
+            /* doesn't morph */
+            DYNSELF.morph(value->vtable->base_type);
+        }
+        if (value->vtable->base_type == enum_class_PerlUndef ||
+                value->vtable->base_type == enum_class_Undef) {
+            DYNSELF.morph(value->vtable->base_type);
+            return;
+        }
+        if (VTABLE_isa(INTERP, value, s_int)) {
+            INTVAL v = VTABLE_get_integer(INTERP, value);
+            DYNSELF.set_integer_native(v);
+            return;
+        }
+        if (VTABLE_isa(INTERP, value, s_num)) {
+            FLOATVAL v = VTABLE_get_number(INTERP, value);
+            DYNSELF.set_number_native(v);
+            return;
+        }
+        if (VTABLE_isa(INTERP, value, s_str)) {
+            STRING* v = VTABLE_get_string(INTERP, value);
+            DYNSELF.set_string_native(v);
+            return;
+        }
+        DYNSELF.morph(value->vtable->base_type);
+        SUPER(value);
+    }
+
+/*
+
 =item C<PMC *clone()>
 
 Creates and returns a clone of the scalar.
@@ -1201,69 +1259,124 @@
 Returns in C<*dest> the result of the logical C<OR> of the scalar and
 C<*value>.
 
+=item C<void i_logical_or(PMC *value)>
+
+Inplace logical or.
+
 =cut
 
 */
 
-    void logical_or (PMC* value,  PMC* dest) {
+    PMC* logical_or (PMC* value,  PMC* dest) {
         if (DYNSELF.get_bool()) {
-            VTABLE_set_pmc(INTERP, dest, SELF);
+            if (!dest)
+                return VTABLE_clone(INTERP, SELF);
+            VTABLE_assign_pmc(INTERP, dest, SELF);
         }
         else {
-            VTABLE_set_pmc(INTERP, dest, value);
+            if (!dest)
+                return VTABLE_clone(INTERP, value);
+            VTABLE_assign_pmc(INTERP, dest, value);
+        }
+        return dest;
+    }
+
+    void i_logical_or (PMC* value) {
+        if (!DYNSELF.get_bool()) {
+            VTABLE_assign_pmc(INTERP, SELF, value);
         }
     }
 
 /*
 
-=item C< void logical_and(PMC *value, PMC *dest)>
+=item C< PMC* logical_and(PMC *value, PMC *dest)>
 
 Returns in C<*dest> the result of the logical C<AND> of the scalar and
 C<*value>.
 
+=item C< void i_logical_and(PMC *value)>
+
+Inplace logical and.
+
 =cut
 
 */
 
-    void logical_and (PMC* value,  PMC* dest) {
+    PMC* logical_and (PMC* value,  PMC* dest) {
         if (DYNSELF.get_bool()) {
-            VTABLE_set_pmc(INTERP, dest, value);
+            if (!dest)
+                return VTABLE_clone(INTERP, value);
+            VTABLE_assign_pmc(INTERP, dest, value);
         }
         else {
-            VTABLE_set_pmc(INTERP, dest, SELF);
+            if (!dest)
+                return VTABLE_clone(INTERP, SELF);
+            VTABLE_assign_pmc(INTERP, dest, SELF);
+        }
+        return dest;
+    }
+
+    void i_logical_and (PMC* value) {
+        if (DYNSELF.get_bool()) {
+            VTABLE_assign_pmc(INTERP, SELF, value);
         }
     }
 
 /*
 
-=item C<void logical_xor(PMC *value, PMC *dest)>
+=item C<PMC* logical_xor(PMC *value, PMC *dest)>
 
 Returns in C<*dest> the result of the logical C<XOR> of the scalar and
 C<*value>.
 
+=item C<void i_logical_xor(PMC *value)>
+
+Inplace logical and.
+
 =cut
 
 */
 
-    void logical_xor (PMC* value,  PMC* dest) {
-
+    PMC* logical_xor (PMC* value,  PMC* dest) {
         INTVAL my_bool, value_bool;
 
         my_bool = DYNSELF.get_bool();
         value_bool = VTABLE_get_bool(INTERP, value);
 
         if (my_bool && ! value_bool) {
-            VTABLE_set_pmc(INTERP, dest, SELF);
+            if (!dest)
+                return VTABLE_clone(INTERP, SELF);
+            VTABLE_assign_pmc(INTERP, dest, SELF);
         }
         else if (value_bool && ! my_bool) {
-            VTABLE_set_pmc(INTERP, dest, value);
+            if (!dest)
+                return VTABLE_clone(INTERP, value);
+            VTABLE_assign_pmc(INTERP, dest, value);
         }
         else {
-            /* XXX - Need a better way to set FALSE */
-            VTABLE_set_integer_native(INTERP, dest, 0);
+            if (!dest)
+                dest = pmc_new(INTERP, SELF->vtable->base_type);
+            VTABLE_set_bool(INTERP, dest, 0);
         }
+        return dest;
     }
 
+    void i_logical_xor (PMC* value) {
+        INTVAL my_bool, value_bool;
+
+        my_bool = DYNSELF.get_bool();
+        value_bool = VTABLE_get_bool(INTERP, value);
+
+        if (my_bool && ! value_bool) {
+            ; /* ok */
+        }
+        else if (value_bool && ! my_bool) {
+            VTABLE_assign_pmc(INTERP, SELF, value);
+        }
+        else {
+            VTABLE_set_bool(INTERP, SELF, 0);
+        }
+    }
 /*
 
 =item C<void logical_not(PMC *dest)>
@@ -1276,9 +1389,7 @@
 */
 
     void logical_not (PMC* dest) {
-        /* XXX - Need a better way to set boolean state */
-        VTABLE_set_integer_native(INTERP, dest,
-            ! DYNSELF.get_bool());
+        VTABLE_set_bool(INTERP, dest, ! DYNSELF.get_bool());
     }
 
 

Modified: trunk/classes/string.pmc
==============================================================================
--- trunk/classes/string.pmc    (original)
+++ trunk/classes/string.pmc    Fri Apr 22 00:56:21 2005
@@ -171,6 +171,8 @@
 
 =item C<VOID set_integer_native(INTVAL value)>
 
+=item C<VOID set_bool(INTVAL value)>
+
 Sets the value of the string to the integer C<value>.
 
 =cut
@@ -181,6 +183,10 @@
         PMC_str_val(SELF) = string_from_int(INTERP, value);
     }
 
+    void set_bool (INTVAL value) {
+        PMC_str_val(SELF) = string_from_int(INTERP, value);
+    }
+
 /*
 
 =item C<VOID set_number_native(FLOATVAL value)>
@@ -256,21 +262,6 @@
     }
 
 /*
-
-=item C<VOID assign_pmc(PMC* value)>
-
-Sets the value of the string to the string value of
-the specified C<PMC>.
-
-=cut
-
-*/
-    void assign_pmc (PMC* value) {
-        STRING *s = VTABLE_get_string(INTERP, value);
-        PMC_str_val(SELF) = string_set(INTERP, PMC_str_val(SELF), s);
-    }
-
-/*
 
 =item C<PMC* bitwise_ors(PMC* value, PMC* dest)>
 

Modified: trunk/dynclasses/pyobject.pmc
==============================================================================
--- trunk/dynclasses/pyobject.pmc       (original)
+++ trunk/dynclasses/pyobject.pmc       Fri Apr 22 00:56:21 2005
@@ -658,7 +658,7 @@
 
 /*
 
-=item C<void logical_and(PMC *value, PMC *dest)>
+=item C<PMC* logical_and(PMC *value, PMC *dest)>
 
 Returns in C<*dest> the result of the logical C<AND> of the scalar and
 C<*value>.
@@ -667,13 +667,24 @@
 
 */
 
-    void logical_and (PMC* value,  PMC* dest) {
+    PMC* logical_and (PMC* value,  PMC* dest) {
         if (DYNSELF.get_bool()) {
+            if (!dest)
+                dest = pmc_new(INTERP, value->vtable->base_type);
             VTABLE_set_pmc(INTERP, dest, value);
         }
         else {
+            if (!dest)
+                dest = pmc_new(INTERP, SELF->vtable->base_type);
             VTABLE_set_pmc(INTERP, dest, SELF);
         }
+        return dest;
+    }
+
+    void i_logical_and (PMC* value) {
+        if (DYNSELF.get_bool()) {
+            VTABLE_set_pmc(INTERP, SELF, value);
+        }
     }
 
 /*
@@ -692,7 +703,7 @@
 
 /*
 
-=item C<void logical_or(PMC *value, PMC *dest)>
+=item C<PMC* logical_or(PMC *value, PMC *dest)>
 
 Returns in C<*dest> the result of the logical C<OR> of the scalar and
 C<*value>.
@@ -701,13 +712,24 @@
 
 */
 
-    void logical_or (PMC* value,  PMC* dest) {
+    PMC* logical_or (PMC* value,  PMC* dest) {
         if (DYNSELF.get_bool()) {
+            if (!dest)
+                dest = pmc_new(INTERP, SELF->vtable->base_type);
             VTABLE_set_pmc(INTERP, dest, SELF);
         }
         else {
+            if (!dest)
+                dest = pmc_new(INTERP, value->vtable->base_type);
             VTABLE_set_pmc(INTERP, dest, value);
         }
+        return dest;
+    }
+
+    void i_logical_or (PMC* value) {
+        if (!DYNSELF.get_bool()) {
+            VTABLE_set_pmc(INTERP, SELF, value);
+        }
     }
 
 /*

Modified: trunk/imcc/parser_util.c
==============================================================================
--- trunk/imcc/parser_util.c    (original)
+++ trunk/imcc/parser_util.c    Fri Apr 22 00:56:21 2005
@@ -407,6 +407,12 @@
     if (strcmp(name, "lsr") == 0)
         return MMD_LSR;
 
+    if (strcmp(name, "or") == 0)
+        return MMD_LOR;
+    if (strcmp(name, "and") == 0)
+        return MMD_LAND;
+    if (strcmp(name, "xor") == 0)
+        return MMD_LXOR;
     /* now try n_<op> */
     if (name[0] == 'n' && name[1] == '_')
         return is_infix(name + 2, n, r);

Modified: trunk/t/pmc/objects.t
==============================================================================
--- trunk/t/pmc/objects.t       (original)
+++ trunk/t/pmc/objects.t       Fri Apr 22 00:56:21 2005
@@ -16,7 +16,7 @@
 
 =cut
 
-use Parrot::Test tests => 60;
+use Parrot::Test tests => 61;
 use Test::More;
 
 output_is(<<'CODE', <<'OUTPUT', "findclass (base class)");
@@ -1912,3 +1912,32 @@
 CODE
 ok
 OUTPUT
+
+pir_output_is(<<'CODE', <<'OUTPUT', "subclassed Integer bug");
+.sub _main @MAIN
+   .local pmc class
+   .local pmc a
+   .local pmc b
+
+    subclass class, "Integer", "LispInteger"
+
+    a = new "LispInteger"
+    b = new "LispInteger"
+
+    a = 1
+    b = 1
+
+    print a
+    print " * "
+    print b
+    print " = "
+
+    a = a * b
+
+    print a
+    print "\n"
+   end
+.end
+CODE
+1 * 1 = 1
+OUTPUT

Modified: trunk/vtable.tbl
==============================================================================
--- trunk/vtable.tbl    (original)
+++ trunk/vtable.tbl    Fri Apr 22 00:56:21 2005
@@ -278,11 +278,13 @@
 INTVAL cmp_num(PMC* value)                   MMD_NUMCMP
 INTVAL cmp_string(PMC* value)                MMD_STRCMP
 
-void logical_or(PMC* value, PMC* dest)       MMD_LOR
+PMC* logical_or(PMC* value, PMC* dest)       MMD_LOR
+PMC* logical_and(PMC* value, PMC* dest)      MMD_LAND
+PMC* logical_xor(PMC* value, PMC* dest)      MMD_LXOR
 
-void logical_and(PMC* value, PMC* dest)      MMD_LAND
-
-void logical_xor(PMC* value, PMC* dest)      MMD_LXOR
+void i_logical_or(PMC* value)                MMD_I_LOR
+void i_logical_and(PMC* value)               MMD_I_LAND
+void i_logical_xor(PMC* value)               MMD_I_LXOR
 
 void logical_not(PMC* dest)
 

Reply via email to