[svn:parrot] r39827 - branches/tt761_keys_revamp/src/pmc

bacek at svn.parrot.org bacek at svn.parrot.org
Mon Jun 29 09:57:58 UTC 2009


Author: bacek
Date: Mon Jun 29 09:57:57 2009
New Revision: 39827
URL: https://trac.parrot.org/parrot/changeset/39827

Log:
[pmc] Add OrderedHashIterator

Added:
   branches/tt761_keys_revamp/src/pmc/orderedhashiterator.pmc
Modified:
   branches/tt761_keys_revamp/src/pmc/orderedhash.pmc

Modified: branches/tt761_keys_revamp/src/pmc/orderedhash.pmc
==============================================================================
--- branches/tt761_keys_revamp/src/pmc/orderedhash.pmc	Mon Jun 29 09:57:36 2009	(r39826)
+++ branches/tt761_keys_revamp/src/pmc/orderedhash.pmc	Mon Jun 29 09:57:57 2009	(r39827)
@@ -77,6 +77,20 @@
 
 /*
 
+=item C<PMC *get_iter()>
+
+Return a new iterator
+
+=cut
+
+*/
+
+    VTABLE PMC *get_iter() {
+        return pmc_new_init(INTERP, enum_class_OrderedHashIterator, SELF);
+    }
+
+/*
+
 =item C<PMC *get_pmc_keyed(PMC *key)>
 
 =item C<PMC *get_pmc_keyed_int(INTVAL key)>

Added: branches/tt761_keys_revamp/src/pmc/orderedhashiterator.pmc
==============================================================================
--- /dev/null	00:00:00 1970	(empty, because file is newly added)
+++ branches/tt761_keys_revamp/src/pmc/orderedhashiterator.pmc	Mon Jun 29 09:57:57 2009	(r39827)
@@ -0,0 +1,265 @@
+/*
+Copyright (C) 2001-2009, Parrot Foundation.
+$Id$
+
+=head1 NAME
+
+src/pmc/orderedhashiterator.pmc - Implementation of Iterator for OrderedHash.
+
+=head1 DESCRIPTION
+
+=head1 SYNOPSIS
+
+=head1 Methods
+
+=over 4
+
+=cut
+
+*/
+
+#include "pmc_hash.h"
+#include "pmc_hashiteratorkey.h"
+
+pmclass OrderedHashIterator extends Iterator no_ro {
+    ATTR PMC        *pmc_hash;      /* the Hash which this Iterator iterates */
+    ATTR Hash       *parrot_hash;   /* Underlying implementation of hash */
+    ATTR INTVAL      pos;           /* */
+    ATTR INTVAL      elements;      /* How many elements left to iterate over */
+    ATTR INTVAL      reverse;       /* Direction of iteration. 1 - for reverse iteration */
+
+/*
+
+=item C<void init_pmc(PMC *initializer)>
+
+Initializes the iterator with an aggregate PMC.
+Defaults iteration mode to iterate from start.
+
+=cut
+
+*/
+
+    VTABLE void init_pmc(PMC *hash) {
+        Parrot_OrderedHashIterator_attributes *attrs =
+            mem_allocate_zeroed_typed(Parrot_OrderedHashIterator_attributes);
+
+        attrs->pmc_hash         = hash;
+        attrs->parrot_hash      = (Hash*)VTABLE_get_pointer(INTERP, hash);
+        attrs->pos              = 0;
+        /* Will be decreased on initial advance_to_next */
+        /* XXX Do we really need to support this use-case ? */
+        attrs->elements         = attrs->parrot_hash->entries;
+        PMC_data(SELF)          = attrs;
+
+        PObj_custom_mark_destroy_SETALL(SELF);
+    }
+
+/*
+
+=item C<void destroy()>
+
+destroys this PMC
+
+=cut
+
+*/
+
+    VTABLE void destroy() {
+        mem_sys_free(PMC_data(SELF));
+    }
+
+/*
+
+=item C<void mark()>
+
+Marks the hash as live.
+
+=cut
+
+*/
+
+    VTABLE void mark() {
+        PMC *hash = PARROT_ORDEREDHASHITERATOR(SELF)->pmc_hash;
+        if (hash)
+             Parrot_gc_mark_PObj_alive(INTERP, (PObj *)hash);
+    }
+
+/*
+
+=item C<PMC *clone()>
+
+=cut
+
+*/
+    VTABLE PMC* clone() {
+        return PMCNULL;
+    }
+
+/*
+
+=item C<void set_integer_native()>
+
+=cut
+
+*/
+    VTABLE void set_integer_native(INTVAL value) {
+        Parrot_OrderedHashIterator_attributes *attrs =
+                PARROT_ORDEREDHASHITERATOR(SELF);
+
+        /* Restart iterator */
+        attrs->elements         = attrs->parrot_hash->entries;
+        if (value == ITERATE_FROM_START || value == ITERATE_FROM_START_KEYS) {
+            attrs->pos      = 0;
+            attrs->reverse  = 0;
+            return;
+        }
+        else if (value == ITERATE_FROM_END) {
+            attrs->pos      = attrs->elements;
+            attrs->reverse  = 1;
+            return;
+        }
+
+        Parrot_ex_throw_from_c_args(INTERP, NULL, EXCEPTION_INVALID_OPERATION,
+                "HashIterator: unknown iterator type");
+    };
+
+/*
+
+=item C<PMC *get_pmc()>
+
+Returns this Iterator's Hash.
+
+=cut
+*/
+    VTABLE PMC* get_pmc() {
+        return PARROT_ORDEREDHASHITERATOR(SELF)->pmc_hash;
+    }
+
+/*
+
+=item C<INTVAL get_bool()>
+
+Returns true if there is more elements to iterate over.
+
+=cut
+
+*/
+
+    VTABLE INTVAL get_bool() {
+        return STATICSELF.elements() > 0;
+    }
+
+/*
+
+=item C<INTVAL elements()>
+
+Returns the number of remaining elements in the Hash.
+
+=cut
+
+*/
+
+    VTABLE INTVAL elements() {
+        return PARROT_ORDEREDHASHITERATOR(SELF)->elements;
+    }
+
+    VTABLE INTVAL get_integer() {
+        return SELF.elements();
+    }
+
+/*
+
+=item C<PMC *shift_pmc()>
+
+Returns the HashIteratorKey for the current position and advance
+the next one.
+
+=cut
+
+*/
+
+    VTABLE PMC *shift_pmc() {
+        Parrot_OrderedHashIterator_attributes *attrs =
+                PARROT_ORDEREDHASHITERATOR(SELF);
+
+        PMC        *ret;
+        HashBucket *bucket;
+
+        if (!attrs->elements)
+            Parrot_ex_throw_from_c_args(INTERP, NULL, EXCEPTION_OUT_OF_BOUNDS,
+                "StopIteration");
+
+        /* Get bucket and move to next bucket */
+        do {
+            bucket = attrs->parrot_hash->bs + attrs->pos++;
+            attrs->elements--;
+        } while(attrs->elements && !bucket->key);
+
+        /* Reuse HashIteratorKey */
+        ret = pmc_new(INTERP, enum_class_HashIteratorKey);
+        /* Poke directly into HIK. We don't want to create any kind of public API for this */
+        PARROT_HASHITERATORKEY(ret)->parrot_hash = attrs->parrot_hash;
+        PARROT_HASHITERATORKEY(ret)->bucket      = bucket;
+
+        return ret;
+    }
+
+/*
+
+=item C<PMC *pop_pmc()>
+
+Returns the HashIteratorKey for the current position and advance
+the next one for reverse iterator.
+
+=cut
+
+*/
+
+    VTABLE PMC *pop_pmc() {
+        Parrot_OrderedHashIterator_attributes *attrs =
+                PARROT_ORDEREDHASHITERATOR(SELF);
+
+        PMC        *ret;
+        HashBucket *bucket;
+
+        if (!attrs->elements)
+            Parrot_ex_throw_from_c_args(INTERP, NULL, EXCEPTION_OUT_OF_BOUNDS,
+                "StopIteration");
+
+        /* Get bucket and move to next bucket */
+        bucket = attrs->parrot_hash->bs + --attrs->pos;
+        attrs->elements--;
+
+        /* Reuse HashIteratorKey */
+        ret = pmc_new(INTERP, enum_class_HashIteratorKey);
+        /* Poke directly into HIK. We don't want to create any kind of public API for this */
+        PARROT_HASHITERATORKEY(ret)->parrot_hash = attrs->parrot_hash;
+        PARROT_HASHITERATORKEY(ret)->bucket      = bucket;
+
+        return ret;
+    }
+
+/*
+
+*/
+
+    VTABLE STRING* shift_string() {
+        PMC *key = SELF.shift_pmc();
+        return VTABLE_get_string(INTERP, key);
+    }
+}
+
+/*
+
+=back
+
+=cut
+
+*/
+
+/*
+ * Local variables:
+ *   c-file-style: "parrot"
+ * End:
+ * vim: expandtab shiftwidth=4:
+ */


More information about the parrot-commits mailing list