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)