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

bacek at svn.parrot.org bacek at svn.parrot.org
Sun Jun 14 10:14:43 UTC 2009


Author: bacek
Date: Sun Jun 14 10:14:42 2009
New Revision: 39556
URL: https://trac.parrot.org/parrot/changeset/39556

Log:
[pmc] Add stripped version of Iterator as ArrayIterator.

Added:
   branches/tt761_keys_revamp/src/pmc/arrayiterator.pmc

Added: branches/tt761_keys_revamp/src/pmc/arrayiterator.pmc
==============================================================================
--- /dev/null	00:00:00 1970	(empty, because file is newly added)
+++ branches/tt761_keys_revamp/src/pmc/arrayiterator.pmc	Sun Jun 14 10:14:42 2009	(r39556)
@@ -0,0 +1,599 @@
+/*
+Copyright (C) 2001-2009, Parrot Foundation.
+$Id$
+
+=head1 NAME
+
+src/pmc/arrayiterator.pmc - Implementation of Iterator for Arrays.
+
+=head1 DESCRIPTION
+
+Generic iterator for traversing arrays.
+
+=head1 SYNOPSIS
+
+=head2 default usage
+
+    .local pmc iterator, array, entry
+    iterator = iter array
+  iter_loop:
+    unless iterator, iter_end  # while (more values)
+    entry = shift iterator     # get an entry
+    ...
+    goto iter_loop
+  iter_end:
+
+
+=head2 iterate from the end, for arrays
+
+    .local pmc iterator, array, entry
+    iterator = iter array
+    iterator = .ITERATE_FROM_END
+  iter_loop:
+    unless iterator, iter_end  # while (more values)
+    entry = pop iterator     # get an entry
+    ...
+    goto iter_loop
+  iter_end:
+
+=head2 Warning!
+
+NB: for different direction you have to use different ops!
+
+TODO: Discuss idea of having separate get_iter/get_reverse_iter VTABLE methods
+to avoid this caveat.
+
+=head1 Methods
+
+=over 4
+
+=cut
+
+*/
+
+pmclass ArrayIterator no_ro {
+    ATTR PMC    *array;     /* the array which this Iterator iterates */
+    ATTR INTVAL  pos;       /* Current position of iterator for forward iterator */
+                            /* Previous position of iterator for reverse iterator */
+    ATTR INTVAL  length;    /* Length of C<array> */
+    ATTR INTVAL  reverse;   /* Direction of iteration. 1 - for reverse iteration */
+
+    void class_init() {
+        if (pass) {
+            /* Make the shift_pmc vtable function available as
+             * a method named "next" */
+            register_nci_method(INTERP, enum_class_ArrayIterator,
+                    F2DPTR(Parrot_ArrayIterator_shift_pmc), "next", "PJO");
+        }
+    }
+
+/*
+
+=item C<void init()>
+
+Raises an exception. Use C<init_pmc()>.
+
+=cut
+
+*/
+
+    VTABLE void init() {
+        Parrot_ex_throw_from_c_args(INTERP, NULL, EXCEPTION_INVALID_OPERATION,
+                "ArrayIterator init without aggregate");
+    }
+
+/*
+
+=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 *array) {
+        Parrot_ArrayIterator_attributes *attrs =
+            mem_allocate_zeroed_typed(Parrot_ArrayIterator_attributes);
+
+        attrs->array     = array;
+        PMC_data(SELF)   = attrs;
+
+        PObj_custom_mark_destroy_SETALL(SELF);
+
+        /* by default, iterate from start */
+        SELF.set_integer_native(ITERATE_FROM_START);
+    }
+
+/*
+
+=item C<void destroy()>
+
+destroys this PMC
+
+=cut
+
+*/
+
+    VTABLE void destroy() {
+        mem_sys_free(PMC_data(SELF));
+    }
+
+/*
+
+=item C<void mark()>
+
+Marks the current idx/key and the aggregate as live.
+
+=cut
+
+*/
+
+    VTABLE void mark() {
+        PMC *array;
+        GET_ATTR_array(INTERP, SELF, array);
+        if (array)
+             Parrot_gc_mark_PObj_alive(INTERP, (PObj *)array);
+    }
+
+/*
+
+=item C<PMC *clone()>
+
+=cut
+
+*/
+    VTABLE PMC* clone() {
+        Parrot_ArrayIterator_attributes *attrs =
+                PARROT_ARRAYITERATOR(SELF);
+        PMC                             *clone =
+                pmc_new_init(INTERP, enum_class_ArrayIterator, attrs->array);
+        Parrot_ArrayIterator_attributes *clone_attrs =
+                PARROT_ARRAYITERATOR(clone);
+
+        clone_attrs->pos     = attrs->pos;
+        clone_attrs->reverse = attrs->reverse;
+        return clone;
+    }
+
+/*
+
+=item C<INTVAL get_bool()>
+
+Returns true if there is more elements to iterate over.
+
+=cut
+
+*/
+
+    VTABLE INTVAL get_bool() {
+        return SELF.elements() > 0;
+    }
+
+/*
+
+=item C<INTVAL elements()>
+
+Returns the number of remaining elements in the array.
+
+=cut
+
+*/
+
+    VTABLE INTVAL elements() {
+        Parrot_ArrayIterator_attributes *attrs =
+                PARROT_ARRAYITERATOR(SELF);
+        if (attrs->reverse)
+            return attrs->pos;
+        else
+            return attrs->length - attrs->pos;
+    }
+
+    VTABLE INTVAL get_integer() {
+        return SELF.elements();
+    }
+
+/*
+
+=item C<void set_integer_native(INTVAL value)>
+
+Reset the Iterator. C<value> must be one of
+
+ ITERATE_FROM_START        ... Iterate from start
+ ITERATE_FROM_END          ... Iterate from end
+
+=cut
+
+*/
+
+    VTABLE void set_integer_native(INTVAL value) {
+        Parrot_ArrayIterator_attributes *attrs =
+                PARROT_ARRAYITERATOR(SELF);
+        if (value == ITERATE_FROM_START) {
+            attrs->reverse   = 0;
+            attrs->pos       = 0;
+            attrs->length    = VTABLE_elements(INTERP, attrs->array);
+        }
+        else if (value == ITERATE_FROM_END) {
+            attrs->reverse   = 1;
+            attrs->pos       = attrs->length
+                             = VTABLE_elements(INTERP, attrs->array);
+        }
+        else
+            Parrot_ex_throw_from_c_args(INTERP, NULL, EXCEPTION_INVALID_OPERATION,
+                    "Wrong direction for ArrayIterator");
+    }
+
+/*
+
+=item C<PMC *get_pmc()>
+
+Returns this Iterator's array.
+
+=cut
+
+*/
+
+    VTABLE PMC *get_pmc() {
+        PMC *array;
+        GET_ATTR_array(INTERP, SELF, array);
+        return array ? array : PMCNULL;
+    }
+
+/*
+
+=item C<INTVAL shift_integer()>
+
+Returns the element for the current idx and sets the idx to
+the next one.
+
+=cut
+
+*/
+
+    VTABLE INTVAL shift_integer() {
+        Parrot_ArrayIterator_attributes *attrs =
+                PARROT_ARRAYITERATOR(SELF);
+
+        if (attrs->pos >= attrs->length)
+            Parrot_ex_throw_from_c_args(INTERP, NULL, EXCEPTION_OUT_OF_BOUNDS,
+                "StopIteration");
+
+        return VTABLE_get_integer_keyed_int(INTERP, attrs->array, attrs->pos++);
+    }
+
+/*
+
+=item C<FLOATVAL shift_float()>
+
+=cut
+
+*/
+
+    VTABLE FLOATVAL shift_float() {
+        Parrot_ArrayIterator_attributes *attrs =
+                PARROT_ARRAYITERATOR(SELF);
+
+        if (!STATICSELF.get_bool())
+            Parrot_ex_throw_from_c_args(INTERP, NULL, EXCEPTION_OUT_OF_BOUNDS,
+                "StopIteration");
+
+        return VTABLE_get_number_keyed_int(INTERP, attrs->array, attrs->pos++);
+    }
+
+
+/*
+
+=item C<STRING *shift_string()>
+
+=cut
+
+*/
+
+    VTABLE STRING *shift_string() {
+        Parrot_ArrayIterator_attributes *attrs =
+                PARROT_ARRAYITERATOR(SELF);
+
+        if (!STATICSELF.get_bool())
+            Parrot_ex_throw_from_c_args(INTERP, NULL, EXCEPTION_OUT_OF_BOUNDS,
+                "StopIteration");
+
+        return VTABLE_get_string_keyed_int(INTERP, attrs->array, attrs->pos++);
+    }
+
+/*
+
+=item C<PMC *shift_pmc()>
+
+Returns the element for the current idx/key and sets the idx/key to
+the next one.
+
+=cut
+
+*/
+
+    VTABLE PMC *shift_pmc() {
+        Parrot_ArrayIterator_attributes *attrs =
+                PARROT_ARRAYITERATOR(SELF);
+
+        if (!STATICSELF.get_bool())
+            Parrot_ex_throw_from_c_args(INTERP, NULL, EXCEPTION_OUT_OF_BOUNDS,
+                "StopIteration");
+
+        return VTABLE_get_pmc_keyed_int(INTERP, attrs->array, attrs->pos++);
+    }
+
+
+/*
+
+=item C<INTVAL pop_integer()>
+
+Returns the element for the current idx and sets the idx to
+the next one.
+
+=cut
+
+*/
+
+    VTABLE INTVAL pop_integer() {
+        Parrot_ArrayIterator_attributes *attrs =
+                PARROT_ARRAYITERATOR(SELF);
+
+        if (!STATICSELF.get_bool())
+            Parrot_ex_throw_from_c_args(INTERP, NULL, EXCEPTION_OUT_OF_BOUNDS,
+                "StopIteration");
+
+        return VTABLE_get_integer_keyed_int(INTERP, attrs->array, --attrs->pos);
+    }
+
+/*
+
+=item C<FLOATVAL pop_float()>
+
+=cut
+
+*/
+
+    VTABLE FLOATVAL pop_float() {
+        Parrot_ArrayIterator_attributes *attrs =
+                PARROT_ARRAYITERATOR(SELF);
+
+        if (!STATICSELF.get_bool())
+            Parrot_ex_throw_from_c_args(INTERP, NULL, EXCEPTION_OUT_OF_BOUNDS,
+                "StopIteration");
+
+        return VTABLE_get_number_keyed_int(INTERP, attrs->array, --attrs->pos);
+    }
+
+
+/*
+
+=item C<STRING *pop_string()>
+
+=cut
+
+*/
+
+    VTABLE STRING *pop_string() {
+        Parrot_ArrayIterator_attributes *attrs =
+                PARROT_ARRAYITERATOR(SELF);
+
+        if (!STATICSELF.get_bool())
+            Parrot_ex_throw_from_c_args(INTERP, NULL, EXCEPTION_OUT_OF_BOUNDS,
+                "StopIteration");
+
+        return VTABLE_get_string_keyed_int(INTERP, attrs->array, --attrs->pos);
+    }
+
+/*
+
+=item C<PMC *pop_pmc()>
+
+Returns the element for the current idx/key and sets the idx/key to
+the next one.
+
+=cut
+
+*/
+
+    VTABLE PMC *pop_pmc() {
+        Parrot_ArrayIterator_attributes *attrs =
+                PARROT_ARRAYITERATOR(SELF);
+
+        if (!STATICSELF.get_bool())
+            Parrot_ex_throw_from_c_args(INTERP, NULL, EXCEPTION_OUT_OF_BOUNDS,
+                "StopIteration");
+
+        return VTABLE_get_pmc_keyed_int(INTERP, attrs->array, --attrs->pos);
+    }
+
+/*
+=item C<PMC *get_pmc_keyed(PMC *key)>
+
+Returns the element for C<*key>.
+
+=cut
+
+*/
+
+    VTABLE PMC *get_pmc_keyed(PMC *key) {
+        return STATICSELF.get_pmc_keyed_int(VTABLE_get_integer(INTERP, key));
+    }
+
+/*
+
+=item C<PMC *get_pmc_keyed_int(INTVAL key)>
+
+Returns the element for C<key>.
+
+=cut
+
+*/
+
+    VTABLE PMC *get_pmc_keyed_int(INTVAL idx) {
+        return VTABLE_get_pmc_keyed_int(INTERP, STATICSELF.get_pmc(),
+                PARROT_ARRAYITERATOR(SELF)->pos + idx);
+    }
+/*
+
+=item C<INTVAL get_integer_keyed(PMC *key)>
+
+=cut
+
+*/
+
+    VTABLE INTVAL get_integer_keyed(PMC *key) {
+        return STATICSELF.get_integer_keyed_int(VTABLE_get_integer(INTERP, key));
+    }
+
+/*
+
+=item C<INTVAL get_integer_keyed_int(INTVAL idx)>
+
+Get integer value of current position plus idx.
+
+=cut
+
+*/
+
+    VTABLE INTVAL get_integer_keyed_int(INTVAL idx) {
+        return VTABLE_get_integer_keyed_int(INTERP, STATICSELF.get_pmc(),
+                PARROT_ARRAYITERATOR(SELF)->pos + idx);
+    }
+
+/*
+
+=item C<FLOATVAL get_number_keyed(PMC *key)>
+
+=cut
+
+*/
+
+    VTABLE FLOATVAL get_number_keyed(PMC *key) {
+        return STATICSELF.get_number_keyed_int(VTABLE_get_integer(INTERP, key));
+    }
+
+/*
+
+=item C<FLOATVAL get_number_keyed_int(INTVAL idx)>
+
+Get number value of current position plus idx.
+
+=cut
+
+*/
+
+    VTABLE FLOATVAL get_number_keyed_int(INTVAL idx) {
+        return VTABLE_get_number_keyed_int(INTERP, STATICSELF.get_pmc(),
+                PARROT_ARRAYITERATOR(SELF)->pos + idx);
+    }
+
+
+
+/*
+
+=item C<STRING *get_string_keyed(PMC *key)>
+
+=cut
+
+*/
+
+    VTABLE STRING *get_string_keyed(PMC *key) {
+        return STATICSELF.get_string_keyed_int(VTABLE_get_integer(INTERP, key));
+    }
+
+/*
+
+=item C<STRING *get_string_keyed_int(INTVAL idx)>
+
+Get string value of current position plus idx.
+
+=cut
+
+*/
+
+    VTABLE STRING *get_string_keyed_int(INTVAL idx) {
+        return VTABLE_get_string_keyed_int(INTERP, STATICSELF.get_pmc(),
+                PARROT_ARRAYITERATOR(SELF)->pos + idx);
+    }
+
+/*
+
+=item C<INTVAL exists_keyed(PMC *key)>
+
+Returns whether an element for C<*key> exists in the array.
+
+=cut
+
+*/
+
+    VTABLE INTVAL exists_keyed(PMC *key) {
+        return STATICSELF.exists_keyed_int(VTABLE_get_integer(INTERP, key));
+    }
+
+/*
+
+=item C<INTVAL exists_keyed_int(INTVAL idx)>
+
+Returns whether an element for C<idx> exists in the aggregate.
+
+=cut
+
+*/
+
+    VTABLE INTVAL exists_keyed_int(INTVAL idx) {
+        Parrot_ArrayIterator_attributes *attrs =
+                PARROT_ARRAYITERATOR(SELF);
+        /* Cheat! */
+        INTVAL final_pos = attrs->pos + idx - attrs->reverse;
+
+        return VTABLE_exists_keyed_int(INTERP, attrs->array, final_pos);
+    }
+
+/*
+
+=item C<INTVAL defined_keyed(PMC *key)>
+
+=cut
+
+*/
+
+    VTABLE INTVAL defined_keyed(PMC *key) {
+        return STATICSELF.defined_keyed_int(VTABLE_get_integer(INTERP, key));
+    }
+
+/*
+
+=item C<INTVAL defined_keyed_int(INTVAL key)>
+
+Returns the result of calling C<defined_keyed(key)> on the aggregate.
+
+=cut
+
+*/
+
+    VTABLE INTVAL defined_keyed_int(INTVAL idx) {
+        Parrot_ArrayIterator_attributes *attrs =
+                PARROT_ARRAYITERATOR(SELF);
+        /* Cheat! */
+        INTVAL final_pos = attrs->pos + idx - attrs->reverse;
+
+        return VTABLE_defined_keyed_int(INTERP, attrs->array, final_pos);
+    }
+}
+
+/*
+
+=back
+
+=cut
+
+*/
+
+/*
+ * Local variables:
+ *   c-file-style: "parrot"
+ * End:
+ * vim: expandtab shiftwidth=4:
+ */


More information about the parrot-commits mailing list