Author: leo
Date: Wed Jan 11 08:18:15 2006
New Revision: 11087

Modified:
   trunk/src/classes/key.pmc
   trunk/src/classes/orderedhash.pmc
   trunk/src/classes/unmanagedstruct.pmc
   trunk/t/pmc/orderedhash.t
Log:
OrderedHash - total rewrite

* base OrderedHash on Hash, not PerlArray + Hash
* use hash functionality, as it preserves insertion order already
* adapt tests a bit, unskip one 


Modified: trunk/src/classes/key.pmc
==============================================================================
--- trunk/src/classes/key.pmc   (original)
+++ trunk/src/classes/key.pmc   Wed Jan 11 08:18:15 2006
@@ -305,7 +305,8 @@ PMC_int_val(-1) means end of iteration.
                  * with an Integer KEY
                  */
                  _hash = CONST_STRING(interpreter, "Hash");
-                if (VTABLE_isa(INTERP, agg, _hash))
+                if (VTABLE_isa(INTERP, agg, _hash) &&
+                     agg->vtable->base_type != enum_class_OrderedHash)
                     PObj_get_FLAGS(ret) |= KEY_hash_iterator_FLAGS;
         init:
                 PMC_int_val(ret) = 0;

Modified: trunk/src/classes/orderedhash.pmc
==============================================================================
--- trunk/src/classes/orderedhash.pmc   (original)
+++ trunk/src/classes/orderedhash.pmc   Wed Jan 11 08:18:15 2006
@@ -8,26 +8,30 @@ src/classes/orderedhash.pmc - Ordered Ha
 
 =head1 DESCRIPTION
 
-C<OrderedHash> extends C<PerlArray> to provide the functionality of
-C<PerlArray> (list in C<data>) and a C<Hash> (hash in
-C<struct_val>). The list holds the PMC values, the hash keys point to
-the index of the value in the list.
+C<OrderedHash> extends C<Hash> to provide the interfaces of
+C<array> and C<hash>. To achieve the functionality of an ordered
+hash there are a few restrictions though: C<delete_keyed> never removes 
+items, they are just nulled. 
+
+Please note that if values are set via integer idx, these indices
+have to be in strict order. Using C<push_xx> simplifies this task.
+This creates a key "\1idx" for C<idx> and is therefore not fully transparent.
 
 There are 2 iterator interfaces:
 
 =over 4
 
-=item * retrieve value (in creation order)
+=item * retrieve values (in creation order)
 
-=item * retrieve key (no special order)
+Please note that after a C<delete_keyed> operation, iterating over
+values doesn't work any more, you'll get an error 'No such key'.
+
+=item * retrieve keys (in creation order)
 
 =back
 
 See F<t/pmc/orderedhash.t>.
 
-If values are set by numeric index only, there is no hash key. Iterating
-over the hash doesn't show these values.
-
 =head2 Methods
 
 =over 4
@@ -39,326 +43,364 @@ over the hash doesn't show these values.
 #include "parrot/parrot.h"
 #include "pmc_hash.h"
 
-/*
-
-=item C<static PMC *undef(Interp *interpreter)>
-
-Returns the C<PerlUndef> PMC.
-
-=cut
-
-*/
-
-static PMC* undef(Interp* interpreter)
-{
-    return pmc_new(interpreter, enum_class_PerlUndef);
-}
 
-pmclass OrderedHash extends PerlArray need_ext does array does hash {
+pmclass OrderedHash extends Hash need_ext does array does hash {
 
 /*
 
-=item C<void init()>
-
-Initializes the ordered hash.
+=item C<PMC *get_pmc_keyed(PMC *key)>
 
-=item C<void destroy()>
+=item C<PMC *get_pmc_keyed_int(INTVAL key)>
 
-Destroys the ordered hash.
+=item C<PMC *get_pmc_keyed_str(STRING *key)>
 
 =cut
 
 */
 
-    void init () {
-        /* clear the Hash ptr - its not yet existing */
-        PMC_struct_val(SELF) = NULL;
-        SUPER();
-        Hash.SUPER();
+    PMC* get_pmc_keyed_int (INTVAL idx) {
+        Hash *h = PMC_struct_val(SELF);
+        INTVAL n;
+        HashBucket *b;
+
+        n = h->entries;
+        if (idx < 0)
+            idx += n;
+        if (idx < 0 || idx >= n) {
+            real_exception(INTERP, NULL, KEY_NOT_FOUND,
+                    "OrderedHash: index out of bounds!");
+        }
+        b = h->bs + idx;
+        if (b->key)
+            return (PMC*) b->value;
+        real_exception(INTERP, NULL, KEY_NOT_FOUND,
+                "OrderedHash: No such key");
+        return PMCNULL;
     }
 
-    void destroy () {
-        Hash.SUPER();
+    PMC* get_pmc_keyed (PMC* key) {
+        switch (PObj_get_FLAGS(key) & KEY_type_FLAGS) {
+            case KEY_hash_iterator_FLAGS:
+                return SUPER(key);
+            case KEY_integer_FLAG:
+                return SELF.get_pmc_keyed_int(key_integer(INTERP, key));
+            default:
+                return SUPER(key);
+        }
     }
 
 /*
 
-=item C<void mark()>
-
-Marks the ordered hash as live.
-
-=cut
-
-*/
-
-    void mark () {
-        SUPER();
-        Hash.SUPER();
-    }
-
-/*
+=item C<STRING *get_string_keyed(PMC *key)>
 
-=item C<PMC *clone()>
+=item C<STRING *get_string_keyed_int(INTVAL key)>
 
-Creates and returns a clone of the ordered hash.
+=item C<STRING *get_string_keyed_str(STRING *key)>
 
 =cut
 
 */
 
-    PMC* clone () {
-        PMC* dest = SUPER();
-        hash_clone(INTERP, (Hash *)PMC_struct_val(SELF),
-            (Hash**)&PMC_struct_val(dest));
-        return dest;
-    }
-
-/*
-
-=item C<PMC *get_pmc_keyed(PMC *key)>
-
-=cut
-
-*/
+    STRING* get_string_keyed_int (INTVAL idx) {
+        Hash *h = PMC_struct_val(SELF);
+        INTVAL n;
+        HashBucket *b;
 
-    PMC* get_pmc_keyed (PMC* key) {
-        if (PObj_get_FLAGS(key) & KEY_integer_FLAG) {
-            return SUPER(key);
-        }
-        else {
-            INTVAL n = Hash.SELF.get_integer_keyed(key);
-            return DYNSELF.get_pmc_keyed_int(n);
+        n = h->entries;
+        if (idx < 0)
+            idx += n;
+        if (idx < 0 || idx >= n) {
+            real_exception(INTERP, NULL, KEY_NOT_FOUND,
+                    "OrderedHash: index out of bounds!");
         }
+        b = h->bs + idx;
+        if (b->key)
+            return VTABLE_get_string(INTERP, (PMC*) b->value);
+        real_exception(INTERP, NULL, KEY_NOT_FOUND,
+                "OrderedHash: No such key");
+        return NULL;
     }
 
+    STRING* get_string_keyed (PMC* key) {
+        switch (PObj_get_FLAGS(key) & KEY_type_FLAGS) {
+            case KEY_hash_iterator_FLAGS:
+                return SUPER(key);
+            case KEY_integer_FLAG:
+                return SELF.get_string_keyed_int(key_integer(INTERP, key));
+            default:
+                return SUPER(key);
+        }
+    }
 /*
 
-=item C<PMC *get_pmc_keyed_str(STRING *key)>
-
-Returns the PMC value associated with C<*key>.
-
-=cut
-
-*/
+=item C<INTVAL get_integer_keyed(PMC *key)>
 
-    PMC* get_pmc_keyed_str (STRING* key) {
-        INTVAL n = Hash.SELF.get_integer_keyed_str(key);
-        return DYNSELF.get_pmc_keyed_int(n);
-    }
+=item C<INTVAL get_integer_keyed_str(STRING *key)>
 
-/*
+=item C<INTVAL get_integer_keyed_int(INTVAL key)>
 
-=item C<INTVAL get_integer_keyed_str(STRING *key)>
+Returns the integer value associated with C<key>. 
 
 =cut
 
 */
 
-    INTVAL get_integer_keyed_str (STRING* key) {
-        INTVAL n = Hash.SELF.get_integer_keyed_str(key);
-        return DYNSELF.get_integer_keyed_int(n);
-    }
-
-/*
-
-=item C<INTVAL get_integer_keyed(PMC *key)>
-
-Returns the integer value associated with C<*key>.
 
-=cut
+    INTVAL get_integer_keyed_int (INTVAL idx) {
+        Hash *h = PMC_struct_val(SELF);
+        INTVAL n;
+        HashBucket *b;
 
-*/
+        n = h->entries;
+        if (idx < 0)
+            idx += n;
+        if (idx < 0 || idx >= n) {
+            real_exception(INTERP, NULL, OUT_OF_BOUNDS,
+                    "OrderedHash: index out of bounds!");
+        }
+        b = h->bs + idx;
+        if (b->key)
+            return VTABLE_get_integer(INTERP, (PMC*) b->value);
+        real_exception(INTERP, NULL, KEY_NOT_FOUND,
+                "OrderedHash: No such key");
+        return 0;
+    }
 
     INTVAL get_integer_keyed (PMC* key) {
-        INTVAL n = Hash.SELF.get_integer_keyed(key);
-        return DYNSELF.get_integer_keyed_int(n);
+        switch (PObj_get_FLAGS(key) & KEY_type_FLAGS) {
+            case KEY_hash_iterator_FLAGS:
+                return SUPER(key);
+            case KEY_integer_FLAG:
+                return SELF.get_integer_keyed_int(key_integer(INTERP, key));
+            default:
+                return SUPER(key);
+        }
     }
 
 /*
 
 =item C<FLOATVAL get_number_keyed(PMC *key)>
 
-Returns the floating-point value for the element at C<*key>.
+=item C<FLOATVAL get_number_keyed_int(INTVAL key)>
+
+=item C<FLOATVAL get_number_keyed_str(STRING* key)>
+
+Returns the floating-point value for the element at C<key>.
 
 =cut
 
 */
 
+    FLOATVAL get_number_keyed_int (INTVAL idx) {
+        Hash *h = PMC_struct_val(SELF);
+        INTVAL n;
+        HashBucket *b;
+
+        n = h->entries;
+        if (idx < 0)
+            idx += n;
+        if (idx < 0 || idx >= n) {
+            real_exception(INTERP, NULL, OUT_OF_BOUNDS,
+                    "OrderedHash: index out of bounds!");
+        }
+        b = h->bs + idx;
+        if (b->key)
+            return VTABLE_get_number(INTERP, (PMC*) b->value);
+        real_exception(INTERP, NULL, KEY_NOT_FOUND,
+                "OrderedHash: No such key");
+        return 0.0;
+    }
+
     FLOATVAL get_number_keyed (PMC* key) {
-        INTVAL n = Hash.SELF.get_integer_keyed(key);
-        return DYNSELF.get_number_keyed_int(n);
+        switch (PObj_get_FLAGS(key) & KEY_type_FLAGS) {
+            case KEY_hash_iterator_FLAGS:
+                return SUPER(key);
+            case KEY_integer_FLAG:
+                return SELF.get_number_keyed_int(key_integer(INTERP, key));
+            default:
+                return SUPER(key);
+        }
     }
 
 /*
 
-=item C<void set_pmc_keyed(PMC *key, PMC *value)>
-
-Associates C<*value> with C<*key>.
-
-=cut
-
-*/
+=item C<void set_pmc_keyed_int(INTVAL idx, PMC *val)>
 
-    void set_pmc_keyed (PMC* key, PMC* value) {
-        INTVAL n = DYNSELF.elements();
-        DYNSELF.set_pmc_keyed_int(n, value);
-        Hash.SELF.set_integer_keyed(key, n);
-    }
+=item C<void set_integer_keyed_int(INTVAL key, INTVAL value)>
 
-/*
+=item C<void set_number_keyed_int(INTVAL key, FLOATVAL value)>
 
-=item C<void set_integer_keyed(PMC *key, INTVAL value)>
+=item C<void set_string_keyed_int(INTVAL key, STRING *value)>
 
-Associates C<value> with C<*key>.
+Sets the PMC value of the element at index C<key> to C<val>.
+The created key = "\1idx".
 
 =cut
 
 */
 
-    void set_integer_keyed (PMC* key, INTVAL value) {
-        INTVAL n = DYNSELF.elements();
-        DYNSELF.set_integer_keyed_int(n, value);
-        Hash.SELF.set_integer_keyed(key, n);
-    }
-
-/*
-
-=item C<void set_string_keyed(PMC *key, STRING *value)>
+    void set_pmc_keyed_int (INTVAL idx, PMC* val) {
+        STRING *key, *fmt;
+        Hash *h = PMC_struct_val(SELF);
+        INTVAL n;
+        HashBucket *b;
 
-Associates C<value> with C<*key>.
-
-=cut
+        n = h->entries;
+        if (idx < -n)
+            idx = -idx - n - 1;
+        else if (idx < 0)
+            idx += n;
+        fmt = CONST_STRING(INTERP, "\1%d");
+        if (idx >= n) {
+            /* TODO warn or fill if there are holes */
+            key = Parrot_sprintf_s(INTERP, fmt, idx);
+            DYNSELF.set_pmc_keyed_str(key, val);
+        }
+        else {
+            b = h->bs + idx;
+            if (!b->key) {
+                b->key = Parrot_sprintf_s(INTERP, fmt, idx);
+            }
+            b->value = val;
+        }
+    }
 
-*/
+    void set_integer_keyed_int (INTVAL idx, INTVAL value) {
+        PMC *v = pmc_new(INTERP, Parrot_get_ctx_HLL_type(INTERP,
+                    enum_class_Integer));
+        VTABLE_set_integer_native(INTERP, v, value);
+        SELF.set_pmc_keyed_int(idx, v);
+    }
 
-    void set_string_keyed (PMC* key, STRING* value) {
-        INTVAL n = DYNSELF.elements();
-        DYNSELF.set_string_keyed_int(n, value);
-        Hash.SELF.set_integer_keyed(key, n);
+    void set_number_keyed_int (INTVAL idx, FLOATVAL value) {
+        PMC *v = pmc_new(INTERP, Parrot_get_ctx_HLL_type(INTERP,
+                    enum_class_Float));
+        VTABLE_set_number_native(INTERP, v, value);
+        SELF.set_pmc_keyed_int(idx, v);
     }
 
+    void set_string_keyed_int (INTVAL idx, STRING* value) {
+        PMC *v = pmc_new(INTERP, Parrot_get_ctx_HLL_type(INTERP,
+                    enum_class_String));
+        VTABLE_set_string_native(INTERP, v, value);
+        SELF.set_pmc_keyed_int(idx, v);
+    }
 /*
 
-=item C<void set_pmc_keyed_str(STRING *key, PMC *value)>
-
-Associates C<*value> with C<*key>.
-
-=cut
-
-*/
-
-    void set_pmc_keyed_str (STRING* key, PMC* value) {
-        INTVAL n = DYNSELF.elements();
-        DYNSELF.set_pmc_keyed_int(n, value);
-        Hash.SELF.set_integer_keyed_str(key, n);
-    }
+=item C<void push_float(FLOATVAL value)>
 
-/*
+=item C<void push_integer(INTVAL value)>
 
-=item C<void set_integer_keyed_str(STRING *key, INTVAL value)>
+=item C<void push_pmc(PMC* value)>
 
-Associates C<value> with C<*key>.
+=item C<void push_string(STRING* value)>
 
 =cut
 
 */
 
-    void set_integer_keyed_str (STRING* key, INTVAL value) {
+    void push_pmc(PMC* value) {
         INTVAL n = DYNSELF.elements();
-        DYNSELF.set_integer_keyed_int(n, value);
-        Hash.SELF.set_integer_keyed_str(key, n);
+        SELF.set_pmc_keyed_int(n, value);
     }
 
-/*
-
-=item C<void set_number_keyed (PMC *key, FLOATVAL value)>
-
-=cut
-
-*/
-
-    void set_number_keyed (PMC* key, FLOATVAL value) {
+    void push_float(FLOATVAL value) {
         INTVAL n = DYNSELF.elements();
-        DYNSELF.set_number_keyed_int(n, value);
-        Hash.SELF.set_integer_keyed(key, n);
+        SELF.set_number_keyed_int(n, value);
     }
 
-/*
-
-=item C<void set_string_keyed_str(STRING *key, STRING *value)>
-
-=cut
-
-*/
+    void push_integer(INTVAL value) {
+        INTVAL n = DYNSELF.elements();
+        SELF.set_integer_keyed_int(n, value);
+    }
 
-    void set_string_keyed_str (STRING* key, STRING* value) {
+    void push_string(STRING* value) {
         INTVAL n = DYNSELF.elements();
-        DYNSELF.set_string_keyed_int(n, value);
-        Hash.SELF.set_integer_keyed_str(key, n);
+        SELF.set_string_keyed_int(n, value);
     }
 
 /*
 
 =item C<INTVAL exists_keyed(PMC *key)>
 
+=item C<INTVAL exists_keyed_str(STRING *key)>
+
+=item C<INTVAL exists_keyed_int(INTVAL key)>
+
 =cut
 
 */
 
+    INTVAL exists_keyed_int(INTVAL idx) {
+        Hash *h = PMC_struct_val(SELF);
+        INTVAL n;
+        HashBucket *b;
+
+        n = h->entries;
+        if (idx < 0)
+            idx += n;
+        if (idx < 0 || idx >= n) {
+            return 0;
+        }
+        b = h->bs + idx;
+        if (b->key)
+            return 1;
+        return 0;
+    }
     INTVAL exists_keyed(PMC* key) {
         if (PObj_get_FLAGS(key) & KEY_integer_FLAG) {
-            return SUPER(key);
+            return SELF.exists_keyed_int(key_integer(INTERP, key));
         }
         else {
-            return Hash.SUPER(key);
+            /* TODO handle composite keys */
+            return SELF.exists_keyed_str(key_string(INTERP, key));
         }
     }
 
-/*
-
-=item C<INTVAL exists_keyed_str(STRING *key)>
-
-Returns whether the key C<*key> exists in the hash.
-
-=cut
-
-*/
-
     INTVAL exists_keyed_str(STRING* key) {
-        return Hash.SUPER(key);
+        Hash *h = PMC_struct_val(SELF);
+        HashBucket *b;
+        b = hash_get_bucket(INTERP, h, key);
+        if (b && b->key)
+            return 1;
+        return 0;
     }
 
 /*
 
 =item C<INTVAL defined_keyed(PMC *key)>
 
+=item C<INTVAL defined_keyed_str(STRING *key)>
+
+=item C<INTVAL defined_keyed_int(INTVAL key)>
+
 =cut
 
 */
 
-    INTVAL defined_keyed(PMC* key) {
+
+    INTVAL defined_keyed(PMC *key) {
         if (PObj_get_FLAGS(key) & KEY_integer_FLAG) {
-            return SUPER(key);
-        }
-        else {
-            INTVAL n = Hash.SELF.get_integer_keyed(key);
-            return DYNSELF.defined_keyed_int(n);
+            return SELF.defined_keyed_int(key_integer(INTERP, key));
         }
+        return SUPER(key);
     }
 
-/*
-
-=item C<INTVAL defined_keyed_str(STRING *key)>
-
-Returns whether the value for key C<*key> is defined in the hash.
-
-=cut
-
-*/
-
-    INTVAL defined_keyed_str(STRING* key) {
-        INTVAL n = Hash.SELF.get_integer_keyed_str(key);
-        return DYNSELF.defined_keyed_int(n);
+    INTVAL defined_keyed_int(INTVAL idx) {
+        Hash *h = PMC_struct_val(SELF);
+        INTVAL n;
+        HashBucket *b;
+
+        n = h->entries;
+        if (idx < 0)
+            idx += n;
+        if (idx < 0 || idx >= n) {
+            return 0;
+        }
+        b = h->bs + idx;
+        if (b->key)
+            return VTABLE_defined(INTERP, (PMC*)b->value);
+        return 0;
     }
 
 /*
@@ -367,6 +409,8 @@ Returns whether the value for key C<*key
 
 =item C<void delete_keyed_str(STRING *key)>
 
+=item C<void delete_keyed_int(INTVAL key)>
+
 Deletes the key C<*key> from the hash.
 
 =cut
@@ -375,45 +419,72 @@ Deletes the key C<*key> from the hash.
 
     void delete_keyed(PMC* key) {
         if (PObj_get_FLAGS(key) & KEY_integer_FLAG) {
-            SUPER(key);
+            SELF.delete_keyed_int(key_integer(INTERP, key));
         }
         else {
-            PMC *new_undef = undef(INTERP);
-            /* fetch index into the PerlArray
-               and delete the key in the Hash afterward */
-            INTVAL n = Hash.SELF.get_integer_keyed(key);
-            Hash.SUPER(key);
-            /* remove the value from the PerlArray,
-               but don't splice the PerlArray. We don't want to mess up
-               the mapping from the Hash to the PerlArray */
-            DYNSELF.set_pmc_keyed_int(n,new_undef);
+            /* TODO handle composite keys */
+            SELF.delete_keyed_str(key_string(INTERP, key));
         }
     }
 
+    void delete_keyed_int(INTVAL idx) {
+        Hash *h = PMC_struct_val(SELF);
+        INTVAL n;
+        HashBucket *b;
+
+        n = h->entries;
+        if (idx < 0)
+            idx += n;
+        if (idx < 0 || idx >= n) {
+            return;
+        }
+        b = h->bs + idx;
+        if (b)
+            b->key = NULL;
+    }
+
     void delete_keyed_str(STRING* key) {
-        PMC *new_undef = undef(INTERP);
-        /* fetch index into the PerlArray
-           and delete the key in the Hash afterward */
-        INTVAL n = Hash.SELF.get_integer_keyed_str(key);
-        Hash.SUPER(key);
-        /* remove the value from the PerlArray,
-           but don't splice the PerlArray. We don't want to mess up
-           the mapping from the Hash to the PerlArray */
-        DYNSELF.set_pmc_keyed_int(n,new_undef);
+        Hash *h = PMC_struct_val(SELF);
+        HashBucket *b;
+        b = hash_get_bucket(INTERP, h, key);
+        if (b)
+            b->key = NULL;
     }
 
 /*
 
-=item C<STRING *get_string_keyed(PMC *key)>
+=item C<PMC* clone()>
 
-Returns the Parrot string associated with C<*key>.
+Create a clone of the OrderedHash. Non-existent keys are compacted.
+Accessing the clone via integers has different indices, if items
+were deleted
 
 =cut
 
 */
 
-    STRING* get_string_keyed (PMC* key) {
-        return Hash.SUPER(key);
+    PMC* clone() {
+        PMC *dest;
+        Hash *hash = PMC_struct_val(SELF), *h_dest;
+
+        UINTVAL i;
+        HashBucket *b;
+        void *key;
+        void *valtmp;
+
+        dest = pmc_new_noinit(INTERP, SELF->vtable->base_type);
+        new_pmc_hash_x(INTERP, dest, hash->entry_type,
+                hash->key_type, hash->compare, hash->hash_val);
+        h_dest = PMC_struct_val(dest);
+        for (i = 0; i <= hash->mask; i++) {
+            b = hash->bs + i;
+            key = b->key;
+            if (!key)
+                continue;
+            valtmp = VTABLE_clone(INTERP, (PMC*)b->value);
+            hash_put(INTERP, h_dest, key, valtmp);
+        }
+        return dest;
     }
 }
 

Modified: trunk/src/classes/unmanagedstruct.pmc
==============================================================================
--- trunk/src/classes/unmanagedstruct.pmc       (original)
+++ trunk/src/classes/unmanagedstruct.pmc       Wed Jan 11 08:18:15 2006
@@ -89,7 +89,7 @@ key_2_idx(Interp* interpreter, PMC *pmc,
                 key_string(interpreter, key));
             if (!b)
                 internal_exception(1, "key doesn't exist");
-            ix = VTABLE_get_integer(interpreter, (PMC*) b->value);
+            ix = b - hash->bs;
         }
         else
             internal_exception(1, "unhandled type aggregate");

Modified: trunk/t/pmc/orderedhash.t
==============================================================================
--- trunk/t/pmc/orderedhash.t   (original)
+++ trunk/t/pmc/orderedhash.t   Wed Jan 11 08:18:15 2006
@@ -119,11 +119,11 @@ OUT
 output_is(<<'CODE', <<OUT, "idx only");
     new P0, .OrderedHash
     new P1, .String
-    set P1, "ok 2\n"
-    set P0[1], P1
-    new P1, .String
     set P1, "ok 1\n"
     set P0[0], P1
+    new P1, .String
+    set P1, "ok 2\n"
+    set P0[1], P1
 
     set P2, P0[0]
     print P2
@@ -268,20 +268,22 @@ output_is(<<'CODE', <<OUT, "delete");
     delete P0["a"]
 
     new P2, .Iterator, P0
-    set P2, .ITERATE_FROM_START
+    set P2, .ITERATE_FROM_START_KEYS
 iter_loop:
     unless P2, end_iter
-    shift P3, P2
+    shift S3, P2
+    set P3, P2[S3]
     print P3
     branch iter_loop
 end_iter:
 
     delete P0[0]
 
-    set P2, .ITERATE_FROM_START
+    set P2, .ITERATE_FROM_START_KEYS
 iter_loop2:
     unless P2, end_iter2
-    shift P3, P2
+    shift S3, P2
+    set P3, P2[S3]
     print P3
     branch iter_loop2
 end_iter2:
@@ -293,8 +295,6 @@ ok 3
 ok 3
 OUT
 
-SKIP: {
-    skip("Mixing keyed & indexed access is broken - see ticket 33641", 1);
 output_is(<<'CODE', <<'OUTPUT', "delete with int keys");
     new P0, .OrderedHash
     set P0["abc"], "Foo"
@@ -315,11 +315,11 @@ output_is(<<'CODE', <<'OUTPUT', "delete 
     print I0
     exists I0, P0[2]
     print I0
+    print "\n"
     end
 CODE
-101110
+101101
 OUTPUT
-}
 
 output_like(<<'CODE', '/[axj]/', "iterate over keys");
     .include "iterator.pasm"
@@ -493,7 +493,7 @@ pir_output_is(<< 'CODE', << 'OUTPUT', "O
     end
 .end
 CODE
--16.160000
+-16.16
 OUTPUT
 
 pir_output_is(<< 'CODE', << 'OUTPUT', "OrderedHash get_integer");

Reply via email to