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

bacek at svn.parrot.org bacek at svn.parrot.org
Thu Jun 25 21:27:08 UTC 2009


Author: bacek
Date: Thu Jun 25 21:27:07 2009
New Revision: 39780
URL: https://trac.parrot.org/parrot/changeset/39780

Log:
[pmc] Implement StringIterator.

Added:
   branches/tt761_keys_revamp/src/pmc/stringiterator.pmc
Modified:
   branches/tt761_keys_revamp/src/pmc/iterator.pmc
   branches/tt761_keys_revamp/src/pmc/string.pmc

Modified: branches/tt761_keys_revamp/src/pmc/iterator.pmc
==============================================================================
--- branches/tt761_keys_revamp/src/pmc/iterator.pmc	Thu Jun 25 21:26:47 2009	(r39779)
+++ branches/tt761_keys_revamp/src/pmc/iterator.pmc	Thu Jun 25 21:27:07 2009	(r39780)
@@ -17,7 +17,7 @@
 =head2 default usage
 
     .local pmc iterator, array, entry
-    iterator = new 'Iterator', array
+    iterator = iter array
   iter_loop:
     unless iterator, iter_end  # while (more values)
     entry = shift iterator     # get an entry
@@ -25,14 +25,10 @@
     goto iter_loop
   iter_end:
 
-The C<new> can alternatively be written as:
-
-  iterator = iter array
-
 =head2 iterate from the end, for arrays
 
     .local pmc iterator, array, entry
-    iterator = new 'Iterator', array
+    iterator = iter array
     iterator = .ITERATE_FROM_END
   iter_loop:
     unless iterator, iter_end  # while (more values)
@@ -44,7 +40,7 @@
 =head2 iterate over a hash
 
     .local pmc iterator, hash, key, entry
-    iterator = new 'Iterator', hash
+    iterator = iter hash
   iter_loop:
     unless iterator, iter_end  # while (more values)
     key   = shift iterator     # get the key..
@@ -91,7 +87,9 @@
 
     VTABLE void init_pmc(PMC *aggregate) {
         if (VTABLE_does(INTERP, aggregate, CONST_STRING(INTERP, "array"))
-            || VTABLE_does(INTERP, aggregate, CONST_STRING(INTERP, "hash"))) {
+            || VTABLE_does(INTERP, aggregate, CONST_STRING(INTERP, "hash"))
+            || VTABLE_does(INTERP, aggregate, CONST_STRING(INTERP, "string"))
+            ) {
             /* It's ugly hack... But I cant figure out proper way to do it. */
             PMC *real_iter = VTABLE_get_iter(INTERP, aggregate);
             SELF = pmc_reuse_init(INTERP, SELF, VTABLE_type(INTERP, real_iter), aggregate, 0);
@@ -156,57 +154,6 @@
 
 /*
 
-=item C<opcode_t *invoke(void *next)>
-
-Return the next element of the aggregate. The return type may depend on
-the aggregate. If there are no more items in the aggregate, I1 .. I4 are
-zero.
-
-See F<docs/pdds/pdd03_calling_conventions.pod>.
-
-=cut
-
-*/
-    VTABLE opcode_t *invoke(void *next) {
-        PMC *agg;
-
-        /* iterator constructor */
-        if (REG_INT(interp, 3) == 1) {
-            PMC * const arg = REG_PMC(interp, 5);
-            PMC *iter;
-
-            if (PObj_is_object_TEST(arg)) {
-                REG_PMC(interp, 5) = VTABLE_get_iter(INTERP, arg);
-                return (opcode_t *)next;
-            }
-
-            REG_PMC(interp, 5) = iter = pmc_new_init(INTERP,
-                    enum_class_Iterator, arg);
-            VTABLE_set_integer_native(INTERP, iter, 0);
-            return (opcode_t *)next;
-        }
-        /* TODO function + sentinel */
-        else if (REG_INT(interp, 3) == 2)
-            Parrot_ex_throw_from_c_args(INTERP, NULL, EXCEPTION_INVALID_OPERATION,
-                    "Iterator: invoke 2 args");
-
-        REG_INT(interp, 1) =
-            REG_INT(interp, 2) =
-            REG_INT(interp, 3) =
-            REG_INT(interp, 4) = 0;
-
-        agg = SELF.get_pmc();
-
-        {
-            PMC * const res    = SELF.shift_pmc();
-            REG_INT(interp, 3) = 1;
-            REG_PMC(interp, 5) = res;
-            return (opcode_t *)next;
-        }
-    }
-
-/*
-
 =item C<INTVAL exists_keyed(PMC *key)>
 
 Returns whether an element for C<*key> exists in the aggregate.

Modified: branches/tt761_keys_revamp/src/pmc/string.pmc
==============================================================================
--- branches/tt761_keys_revamp/src/pmc/string.pmc	Thu Jun 25 21:26:47 2009	(r39779)
+++ branches/tt761_keys_revamp/src/pmc/string.pmc	Thu Jun 25 21:27:07 2009	(r39780)
@@ -811,19 +811,7 @@
     }
 
     VTABLE PMC *get_iter() {
-        STRING     *name     = CONST_STRING(interp, "set_key");
-        PMC * const iter     = pmc_new_init(INTERP, enum_class_Iterator, SELF);
-        PMC * const key      = pmc_new(INTERP, enum_class_Key);
-
-        Parrot_PCCINVOKE(interp, iter, name, "P->", key);
-        PObj_get_FLAGS(key) |= KEY_integer_FLAG;
-
-        if (!Parrot_str_byte_length(INTERP, VTABLE_get_string(INTERP, SELF)))
-            VTABLE_set_integer_native(INTERP, key, -1);
-        else
-            VTABLE_set_integer_native(INTERP, key, 0);
-
-        return iter;
+        return pmc_new_init(INTERP, enum_class_StringIterator, SELF);
     }
 
 /*

Added: branches/tt761_keys_revamp/src/pmc/stringiterator.pmc
==============================================================================
--- /dev/null	00:00:00 1970	(empty, because file is newly added)
+++ branches/tt761_keys_revamp/src/pmc/stringiterator.pmc	Thu Jun 25 21:27:07 2009	(r39780)
@@ -0,0 +1,314 @@
+/*
+Copyright (C) 2001-2009, Parrot Foundation.
+$Id$
+
+=head1 NAME
+
+src/pmc/stringiterator.pmc - StringIterator PMC
+
+=head1 DESCRIPTION
+
+Implementation of Iterator for String PMC.
+
+=head1 SYNOPSIS
+
+
+=head1 Methods
+
+=over 4
+
+=cut
+
+*/
+
+
+pmclass StringIterator extends Iterator {
+    ATTR PMC    *string;    /* String to iterate over */
+    ATTR INTVAL  pos;       /* Current position of iterator for forward iterator */
+                            /* Previous position of iterator for reverse iterator */
+    ATTR INTVAL  length;    /* Length of C<string> */
+    ATTR INTVAL  reverse;   /* Direction of iteration. 1 - for reverse iteration */
+
+/*
+
+=item C<void init_pmc()>
+
+Initialize StringIterator.
+
+=cut
+
+*/
+    VTABLE void init_pmc(PMC *string) {
+        Parrot_StringIterator_attributes *attrs =
+            mem_allocate_zeroed_typed(Parrot_StringIterator_attributes);
+
+        attrs->string    = string;
+        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 *string;
+        GET_ATTR_string(INTERP, SELF, string);
+        if (string)
+             Parrot_gc_mark_PObj_alive(INTERP, (PObj *)string);
+    }
+
+/*
+
+=item C<PMC *clone()>
+
+=cut
+
+*/
+    VTABLE PMC* clone() {
+        Parrot_StringIterator_attributes *attrs =
+                PARROT_STRINGITERATOR(SELF);
+        PMC                              *clone =
+                pmc_new_init(INTERP, enum_class_StringIterator, attrs->string);
+        Parrot_StringIterator_attributes *clone_attrs =
+                PARROT_STRINGITERATOR(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 C<string>.
+
+=cut
+
+*/
+
+    VTABLE INTVAL elements() {
+        Parrot_StringIterator_attributes *attrs =
+                PARROT_STRINGITERATOR(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_StringIterator_attributes *attrs =
+                PARROT_STRINGITERATOR(SELF);
+        if (value == ITERATE_FROM_START) {
+            attrs->reverse   = 0;
+            attrs->pos       = 0;
+            attrs->length    = VTABLE_elements(INTERP, attrs->string);
+        }
+        else if (value == ITERATE_FROM_END) {
+            attrs->reverse   = 1;
+            attrs->pos       = attrs->length
+                             = VTABLE_elements(INTERP, attrs->string);
+        }
+        else
+            Parrot_ex_throw_from_c_args(INTERP, NULL, EXCEPTION_INVALID_OPERATION,
+                    "Wrong direction for StringIterator");
+    }
+
+/*
+
+=item C<PMC *get_pmc()>
+
+Returns this Iterator's string.
+
+=cut
+
+*/
+
+    VTABLE PMC *get_pmc() {
+        PMC *string;
+        GET_ATTR_string(INTERP, SELF, string);
+        return string ? string : PMCNULL;
+    }
+
+/*
+
+=item C<STRING *shift_string()>
+
+Shift next character from C<string>.
+
+=cut
+
+*/
+    VTABLE STRING *shift_string() {
+        Parrot_StringIterator_attributes *attrs =
+                PARROT_STRINGITERATOR(SELF);
+
+        if (attrs->pos >= attrs->length)
+            Parrot_ex_throw_from_c_args(INTERP, NULL, EXCEPTION_OUT_OF_BOUNDS,
+                "StopIteration");
+
+        return VTABLE_get_string_keyed_int(INTERP, attrs->string, attrs->pos++);
+    }
+
+/*
+
+=item C<INTVAL shift_integer()>
+
+Shift next character code from C<string>.
+
+=cut
+
+*/
+    VTABLE INTVAL shift_integer() {
+        Parrot_StringIterator_attributes *attrs =
+                PARROT_STRINGITERATOR(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->string, attrs->pos++);
+    }
+
+/*
+
+=item C<STRING *pop_string()>
+
+Shift "next" character from C<string> for reverse iterator.
+
+=cut
+
+*/
+    VTABLE STRING *pop_string() {
+        Parrot_StringIterator_attributes *attrs =
+                PARROT_STRINGITERATOR(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->string, --attrs->pos);
+    }
+
+/*
+
+=item C<INTVAL pop_integer()>
+
+Shift "next" character code from C<string> for reverse iterator.
+
+=cut
+
+*/
+    VTABLE INTVAL pop_integer() {
+        Parrot_StringIterator_attributes *attrs =
+                PARROT_STRINGITERATOR(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->string, --attrs->pos);
+    }
+
+/*
+
+=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_STRINGITERATOR(SELF)->pos + idx);
+    }
+
+/*
+
+=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_STRINGITERATOR(SELF)->pos + idx);
+    }
+}
+
+
+/*
+
+=back
+
+=cut
+
+*/
+
+/*
+ * Local variables:
+ *   c-file-style: "parrot"
+ * End:
+ * vim: expandtab shiftwidth=4:
+ */


More information about the parrot-commits mailing list