After the overwhelming amount of f'ups to my proposal:
Subject: [RfC] Yet another iterator proposal.
Date: Mon, 10 Mar 2003 16:17:35 +0100
I (as well as our tireless summarizer) thought, the concept ought to be ok.
But a test says more then 1000 RfCs so here is a first step towards implementation:
- only for arrays/integers currently
- only minimal aggregate semantics are implemented for the iterator
- 1 failing test, which is ok:
$ imcc t/pmc/pmc_70.pasm
Iterator init without aggregate
(init could be implemented, then e.g. C<assign PIter, Paggregate> for
attaching the aggregate to the iterator)


Comments welcome :-)
leo

PS playing with the patch needs "make realclean" as well as my latest imcc commit from CVS.
--- parrot/classes/array.pmc    Fri Jan 10 18:05:02 2003
+++ parrot-leo/classes/array.pmc        Sat Mar 22 11:47:14 2003
@@ -537,5 +537,30 @@
        /* XXX */
         return 0;
     }
+
+    PMC* nextkey_keyed (PMC* key, INTVAL what) {
+       PMC *ret = key;
+
+       SELF->cache.int_val = SELF.elements();
+       PObj_get_FLAGS(ret) &= ~KEY_type_FLAGS;
+       PObj_get_FLAGS(ret) |= KEY_integer_FLAG;
+       switch (what) {
+           case 0:     /* reset key, iterate from start */
+               ret->cache.int_val = 0;
+               break;
+           case 1:     /* next key */
+               if (ret->cache.int_val < SELF->cache.int_val)
+                   ++ret->cache.int_val;
+               break;
+           case 2:     /* prev key */
+               if (ret->cache.int_val >= 0)
+                   --ret->cache.int_val;
+               break;
+           case 3:     /* reset key, iterate from end */
+               ret->cache.int_val = SELF->cache.int_val - 1;
+               break;
+       }
+       return ret;
+    }
 }
 
--- parrot/classes/default.pmc  Sun Feb 23 09:19:44 2003
+++ parrot-leo/classes/default.pmc      Fri Mar 21 17:44:24 2003
@@ -1576,17 +1576,17 @@
         DYNSELF.delete_keyed(r_key);
     }
 
-    PMC* nextkey_keyed (PMC* key) {
+    PMC* nextkey_keyed (PMC* key, INTVAL what) {
        internal_exception(ILL_INHERIT,
                "nextkey_keyed() not implemented in class '%s'\n",
                caller(INTERP, SELF));
         return NULL;
     }
 
-    PMC* nextkey_keyed_int (INTVAL* key) {
+    PMC* nextkey_keyed_int (INTVAL* key, INTVAL what) {
         /* XXX - Something's not right with this method */
         PMC* r_key = INT2KEY(INTERP, key);
-        return DYNSELF.nextkey_keyed(r_key);
+        return DYNSELF.nextkey_keyed(r_key, what);
     }
 
     void substr(INTVAL offset, INTVAL length, PMC* dest) {
--- /dev/null   Fri Feb 28 14:27:28 2003
+++ parrot-leo/classes/iterator.pmc     Sat Mar 22 11:39:04 2003
@@ -0,0 +1,413 @@
+/* Iterator.pmc
+ *  Copyright: (When this is determined...it will go here)
+ *  CVS Info
+ *     $Id$
+ *  Overview:
+ *     These are the vtable functions for the Iterator base class
+ *  Data Structure and Algorithms:
+ *  History:
+ *  Notes:
+ *  References:
+ */
+
+#include "parrot/parrot.h"
+
+pmclass Iterator {
+
+    void init () {
+       internal_exception(1, "Iterator init without aggregate\n");
+    }
+
+    void init_pmc (PMC* initializer) {
+       SELF->data = initializer; /* the aggregate itself */
+        SELF->cache.struct_val = NULL;
+        PObj_custom_mark_SET(SELF);
+    }
+
+    void mark () {
+       pobject_lives(INTERP, (PObj *)SELF->data);
+       if (SELF->cache.struct_val)
+            pobject_lives(INTERP, (PObj *) SELF->cache.struct_val);
+    }
+
+    PMC* getprop (STRING* key) {
+        return ((PMC *)SELF->data)->vtable->getprop(INTERP,
+               (PMC *)SELF->data, key);
+    }
+
+    void setprop (STRING* key, PMC* value) {
+        ((PMC *)SELF->data)->vtable->setprop(INTERP,
+                                            (PMC *)SELF->data, key, value);
+    }
+
+    void delprop (STRING* key) {
+        ((PMC *)SELF->data)->vtable->delprop(INTERP, (PMC *)SELF->data, key);
+    }
+
+    PMC* getprops () {
+        return ((PMC *)SELF->data)->vtable->getprops(INTERP, (PMC *)SELF->data);
+    }
+
+    STRING* name () {
+        return whoami;
+    }
+
+
+    void clone (PMC* dest) {
+       /* XXX TODO */
+    }
+
+    INTVAL get_integer () {
+        return ((PMC *)SELF->data)->vtable->get_integer(INTERP,
+               (PMC *)SELF->data);
+    }
+
+    INTVAL get_integer_keyed (PMC* key) {
+       /* XXX adjust index */
+        return ((PMC *)SELF->data)->vtable->get_integer_keyed(INTERP,
+               (PMC *)SELF->data, key);
+    }
+
+    INTVAL get_integer_keyed_int (INTVAL* key) {
+       /* XXX adjust index */
+        return ((PMC *)SELF->data)->vtable->get_integer_keyed_int(INTERP,
+               (PMC *)SELF->data, key);
+    }
+
+    FLOATVAL get_number () {
+        return (FLOATVAL)0;
+    }
+
+    FLOATVAL get_number_keyed (PMC* key) {
+        return (FLOATVAL)0;
+    }
+
+    FLOATVAL get_number_keyed_int (INTVAL* key) {
+        return (FLOATVAL)0;
+    }
+
+    BIGNUM* get_bignum () {
+        return (BIGNUM*)0;
+    }
+
+    BIGNUM* get_bignum_keyed (PMC* key) {
+        return (BIGNUM*)0;
+    }
+
+    BIGNUM* get_bignum_keyed_int (INTVAL* key) {
+        return (BIGNUM*)0;
+    }
+
+    STRING* get_string () {
+        return (STRING*)0;
+    }
+
+    STRING* get_string_keyed (PMC* key) {
+        return (STRING*)0;
+    }
+
+    STRING* get_string_keyed_int (INTVAL* key) {
+        return (STRING*)0;
+    }
+
+    INTVAL get_bool () {
+       PMC *key = SELF->cache.struct_val;
+       PMC *agg = SELF->data;
+        return key && key->cache.int_val >= 0 &&
+           key->cache.int_val < agg->vtable->elements(INTERP, agg);
+    }
+
+    INTVAL get_bool_keyed (PMC* key) {
+        return (INTVAL)0;
+    }
+
+    INTVAL get_bool_keyed_int (INTVAL* key) {
+        return (INTVAL)0;
+    }
+
+    INTVAL elements () {
+        return (INTVAL)0;
+    }
+
+    INTVAL elements_keyed (PMC* key) {
+        return (INTVAL)0;
+    }
+
+    INTVAL elements_keyed_int (INTVAL* key) {
+        return (INTVAL)0;
+    }
+
+    PMC* get_pmc () {
+        return (PMC*)0;
+    }
+
+    PMC* get_pmc_keyed (PMC* key) {
+        return (PMC*)0;
+    }
+
+    PMC* get_pmc_keyed_int (INTVAL* key) {
+        return (PMC*)0;
+    }
+
+    INTVAL is_same (PMC* value) {
+        return (INTVAL)0;
+    }
+
+    INTVAL is_same_keyed (PMC* key, PMC* value, PMC* value_key) {
+        return (INTVAL)0;
+    }
+
+    INTVAL is_same_keyed_int (INTVAL* key, PMC* value, INTVAL* value_key) {
+        return (INTVAL)0;
+    }
+
+    void set_integer (PMC* value) {
+    }
+
+    void set_integer_native (INTVAL value) {
+       PMC *key;
+       if (value < 0 || value > 3)
+           internal_exception(1, "Illegal set_integer on iterator\n");
+       /* reset iterator on aggregate */
+       if (!SELF->cache.struct_val) {
+           SELF->cache.struct_val = key_new(INTERP);
+       }
+       key = SELF->cache.struct_val;
+       SELF->cache.struct_val =
+           ((PMC *)SELF->data)->vtable->nextkey_keyed(INTERP,
+                                                      (PMC *) SELF->data,
+                                                      key, value);
+    }
+
+    void set_integer_same (PMC* value) {
+    }
+
+    void set_integer_keyed (PMC* key, INTVAL value) {
+    }
+
+    void set_integer_keyed_int (INTVAL* key, INTVAL value) {
+    }
+
+    void set_number (PMC* value) {
+    }
+
+    void set_number_native (FLOATVAL value) {
+    }
+
+    void set_number_same (PMC* value) {
+    }
+
+    void set_number_keyed (PMC* key, FLOATVAL value) {
+    }
+
+    void set_number_keyed_int (INTVAL* key, FLOATVAL value) {
+    }
+
+    void set_bignum (PMC* value) {
+    }
+
+    void set_bignum_native (BIGNUM* value) {
+    }
+
+    void set_bignum_same (PMC* value) {
+    }
+
+    void set_bignum_keyed (PMC* key, BIGNUM* value) {
+    }
+
+    void set_bignum_keyed_int (INTVAL* key, BIGNUM* value) {
+    }
+
+    void set_string (PMC* value) {
+    }
+
+    void set_string_native (STRING* value) {
+    }
+
+    void set_string_same (PMC* value) {
+    }
+
+    void set_string_keyed (PMC* key, STRING* value) {
+    }
+
+    void set_string_keyed_int (INTVAL* key, STRING* value) {
+    }
+
+    void set_pmc (PMC* value) {
+    }
+
+    void set_pmc_keyed (PMC* key, PMC* value, PMC* value_key) {
+    }
+
+    void set_pmc_keyed_int (INTVAL* key, PMC* value, INTVAL* value_key) {
+    }
+
+    void set_same (PMC* value) {
+    }
+
+    void set_same_keyed (PMC* key, PMC* value, PMC* value_key) {
+    }
+
+    void set_same_keyed_int (INTVAL* key, PMC* value, INTVAL* value_key) {
+    }
+
+    INTVAL pop_integer () {
+       PMC *key = SELF->cache.struct_val;
+       PMC *agg = SELF->data;
+       INTVAL ret = agg->vtable->get_integer_keyed(INTERP, agg, key);
+       SELF->cache.struct_val =
+           agg->vtable->nextkey_keyed(INTERP, agg, key, 2);
+        return ret;
+    }
+
+    INTVAL pop_integer_keyed (PMC* key) {
+        return (INTVAL)0;
+    }
+
+    INTVAL pop_integer_keyed_int (INTVAL* key) {
+        return (INTVAL)0;
+    }
+
+    FLOATVAL pop_float () {
+        return (FLOATVAL)0;
+    }
+
+    FLOATVAL pop_float_keyed (PMC* key) {
+        return (FLOATVAL)0;
+    }
+
+    FLOATVAL pop_float_keyed_int (INTVAL* key) {
+        return (FLOATVAL)0;
+    }
+
+    BIGNUM* pop_bignum () {
+        return (BIGNUM*)0;
+    }
+
+    BIGNUM* pop_bignum_keyed (PMC* key) {
+        return (BIGNUM*)0;
+    }
+
+    BIGNUM* pop_bignum_keyed_int (INTVAL* key) {
+        return (BIGNUM*)0;
+    }
+
+    STRING* pop_string () {
+        return (STRING*)0;
+    }
+
+    STRING* pop_string_keyed (PMC* key) {
+        return (STRING*)0;
+    }
+
+    STRING* pop_string_keyed_int (INTVAL* key) {
+        return (STRING*)0;
+    }
+
+    PMC* pop_pmc () {
+        return (PMC*)0;
+    }
+
+    PMC* pop_pmc_keyed (PMC* key) {
+        return (PMC*)0;
+    }
+
+    PMC* pop_pmc_keyed_int (INTVAL* key) {
+        return (PMC*)0;
+    }
+
+    INTVAL shift_integer () {
+       PMC *key = SELF->cache.struct_val;
+       PMC *agg = SELF->data;
+       INTVAL ret = agg->vtable->get_integer_keyed(INTERP, agg, key);
+       SELF->cache.struct_val =
+           agg->vtable->nextkey_keyed(INTERP, agg, key, 1);
+        return ret;
+    }
+
+    INTVAL shift_integer_keyed (PMC* key) {
+        return (INTVAL)0;
+    }
+
+    INTVAL shift_integer_keyed_int (INTVAL* key) {
+        return (INTVAL)0;
+    }
+
+    FLOATVAL shift_float () {
+        return (FLOATVAL)0;
+    }
+
+    FLOATVAL shift_float_keyed (PMC* key) {
+        return (FLOATVAL)0;
+    }
+
+    FLOATVAL shift_float_keyed_int (INTVAL* key) {
+        return (FLOATVAL)0;
+    }
+
+    BIGNUM* shift_bignum () {
+        return (BIGNUM*)0;
+    }
+
+    BIGNUM* shift_bignum_keyed (PMC* key) {
+        return (BIGNUM*)0;
+    }
+
+    BIGNUM* shift_bignum_keyed_int (INTVAL* key) {
+        return (BIGNUM*)0;
+    }
+
+    STRING* shift_string () {
+        return (STRING*)0;
+    }
+
+    STRING* shift_string_keyed (PMC* key) {
+        return (STRING*)0;
+    }
+
+    STRING* shift_string_keyed_int (INTVAL* key) {
+        return (STRING*)0;
+    }
+
+    PMC* shift_pmc () {
+        return (PMC*)0;
+    }
+
+    PMC* shift_pmc_keyed (PMC* key) {
+        return (PMC*)0;
+    }
+
+    PMC* shift_pmc_keyed_int (INTVAL* key) {
+        return (PMC*)0;
+    }
+
+    INTVAL exists_keyed (PMC* key) {
+        return (INTVAL)0;
+    }
+
+    INTVAL exists_keyed_int (INTVAL* key) {
+        return (INTVAL)0;
+    }
+
+    INTVAL defined () {
+        return (INTVAL)0;
+    }
+
+    INTVAL defined_keyed (PMC* key) {
+        return (INTVAL)0;
+    }
+
+    INTVAL defined_keyed_int (INTVAL* key) {
+        return (INTVAL)0;
+    }
+
+
+    PMC* nextkey_keyed (PMC* key, INTVAL what) {
+        return (PMC*)0;
+    }
+
+    PMC* nextkey_keyed_int (INTVAL* key, INTVAL what) {
+        return (PMC*)0;
+    }
+
+}
--- /dev/null   Fri Feb 28 14:27:28 2003
+++ parrot-leo/iter.pasm        Sat Mar 22 11:52:23 2003
@@ -0,0 +1,59 @@
+       new P0, .PerlArray      # empty array
+       new P2, .PerlArray      # array with 2 elements
+       push P2, 10
+       push P2, 20
+       set I0, P2
+       new P1, .Iterator, P2
+       print "ok 1\n"
+       set I1, P1
+       eq I0, I1, ok2          # iter.length() == array.length()
+       print "not "
+ok2:   print "ok 2\n"
+       new P1, .Iterator, P0
+       set P1, 0               # reset PIter
+       print "ok 3\n"
+       unless P1, ok4          # if(iter) == false on empty
+       print "not "
+ok4:   print "ok 4\n"
+       new P1, .Iterator, P2
+       set P1, 0               # reset PIter
+       if P1, ok5              # if(iter) == true on non empty
+       print "not "
+ok5:   print "ok 5\n"
+       # now iterate over P2
+       # while (P1) { element = shift(P1) }
+       unless P1, nok6
+        shift I3, P1
+       eq I3, 10, ok6
+nok6:  print "not "
+ok6:   print "ok 6\n"
+       unless P1, nok7
+        shift I3, P1
+       eq I3, 20, ok7
+nok7:  print "not "
+ok7:   print "ok 7\n"
+       unless P1, ok8          # if(iter) == false after last
+       print "not "
+ok8:   print "ok 8\n"
+
+       # now iterate from end
+       set P1, 3               # reset PIter
+       if P1, ok9              # if(iter) == true on non empty
+       print "not "
+ok9:   print "ok 9\n"
+       # while (P1) { element = pop(P1) }
+       unless P1, nok10
+        pop I3, P1
+       eq I3, 20, ok10
+nok10: print "not "
+ok10:  print "ok 10\n"
+       unless P1, nok11
+        pop I3, P1
+       eq I3, 10, ok11
+nok11: print "not "
+ok11:  print "ok 11\n"
+       unless P1, ok12         # if(iter) == false after last
+       print "not "
+ok12:  print "ok 12\n"
+       end
+
--- parrot/vtable.tbl   Sun Feb 23 09:19:44 2003
+++ parrot-leo/vtable.tbl       Fri Mar 21 17:21:01 2003
@@ -318,8 +318,8 @@
 void delete_keyed(PMC* key)
 void delete_keyed_int(INTVAL* key)
 
-PMC* nextkey_keyed(PMC* key)
-PMC* nextkey_keyed_int(INTVAL* key)
+PMC* nextkey_keyed(PMC* key, INTVAL what)
+PMC* nextkey_keyed_int(INTVAL* key, INTVAL what)
 
 void substr(INTVAL offset, INTVAL length, PMC* dest)
 void substr_keyed(PMC* key, INTVAL offset, INTVAL length, PMC* dest, PMC* dest_key)

Reply via email to