cvsuser 04/06/18 05:06:06
Modified: classes key.pmc perlhash.pmc slice.pmc
t/pmc iter.t
Log:
slices 7 - PerlHash slice values
Revision Changes Path
1.22 +22 -5 parrot/classes/key.pmc
Index: key.pmc
===================================================================
RCS file: /cvs/public/parrot/classes/key.pmc,v
retrieving revision 1.21
retrieving revision 1.22
diff -u -w -r1.21 -r1.22
--- key.pmc 17 Jun 2004 16:30:19 -0000 1.21
+++ key.pmc 18 Jun 2004 12:05:59 -0000 1.22
@@ -1,6 +1,6 @@
/*
Copyright: 2001-2003 The Perl Foundation. All Rights Reserved.
-$Id: key.pmc,v 1.21 2004/06/17 16:30:19 leo Exp $
+$Id: key.pmc,v 1.22 2004/06/18 12:05:59 leo Exp $
=head1 NAME
@@ -20,6 +20,17 @@
#include "parrot/parrot.h"
+static int
+is_hash_iter(PMC *agg)
+{
+ if (agg->vtable->base_type == enum_class_PerlHash)
+ return 1;
+ if (agg->vtable->base_type == enum_class_OrderedHash &&
+ (PObj_get_FLAGS(agg) & PObj_private0_FLAG))
+ return 1;
+ return 0;
+}
+
pmclass Key need_ext {
/*
@@ -276,15 +287,21 @@
PObj_get_FLAGS(ret) |= KEY_integer_FLAG;
switch (what) {
case ITERATE_FROM_START: /* reset key */
+ case ITERATE_FROM_START_KEYS:
PMC_int_val(ret) = 0;
if (!n)
PMC_int_val(ret) = -1;
+ if (is_hash_iter(agg))
+ PMC_data(ret) = (void *)INITBucketIndex;
break;
case ITERATE_GET_NEXT:
+ /* src/hash.c:hash_get_idx() advances to next */
+ if (!is_hash_iter(agg)) {
if (PMC_int_val(ret) < n - 1)
++PMC_int_val(ret);
else
PMC_int_val(ret) = -1;
+ }
break;
case ITERATE_GET_PREV:
if (PMC_int_val(ret) >= 0)
1.72 +13 -13 parrot/classes/perlhash.pmc
Index: perlhash.pmc
===================================================================
RCS file: /cvs/public/parrot/classes/perlhash.pmc,v
retrieving revision 1.71
retrieving revision 1.72
diff -u -w -r1.71 -r1.72
--- perlhash.pmc 17 Jun 2004 11:11:54 -0000 1.71
+++ perlhash.pmc 18 Jun 2004 12:05:59 -0000 1.72
@@ -1,6 +1,6 @@
/*
Copyright: 2001-2003 The Perl Foundation. All Rights Reserved.
-$Id: perlhash.pmc,v 1.71 2004/06/17 11:11:54 leo Exp $
+$Id: perlhash.pmc,v 1.72 2004/06/18 12:05:59 leo Exp $
=head1 NAME
@@ -815,6 +815,10 @@
/*
+=item C<PMC* slice (PMC *key)>
+
+Return a new iterator for the slice PMC C<key>
+
=item C<PMC *nextkey_keyed(PMC *key, INTVAL what)>
Returns the next key relative to the location specified in C<what>.
@@ -823,28 +827,24 @@
*/
+ PMC* slice (PMC* key) {
+ PMC *iter = pmc_new_init(interpreter, enum_class_Iterator, SELF);
+ PMC_struct_val(iter) = key;
+ return iter;
+ }
+
PMC* nextkey_keyed (PMC* key, INTVAL what) {
- PMC *ret = key;
- INTVAL n = SELF.elements();
- PObj_get_FLAGS(ret) &= ~KEY_type_FLAGS;
- PObj_get_FLAGS(ret) |= KEY_integer_FLAG;
switch (what) {
case ITERATE_FROM_START: /* reset key */
case ITERATE_FROM_START_KEYS:
- PMC_int_val(ret) = 0;
- if (!n)
- PMC_int_val(ret) = -1;
- PMC_data(ret) = (void *)INITBucketIndex;
- break;
case ITERATE_GET_NEXT:
- /* do nothing: hash_get_idx does increment the idx */
- break;
+ return VTABLE_nextkey_keyed(interpreter, key, SELF, what);
default:
internal_exception(1, "Can't iterate from end\n");
break;
}
- return ret;
+ return key;
}
/*
1.3 +22 -4 parrot/classes/slice.pmc
Index: slice.pmc
===================================================================
RCS file: /cvs/public/parrot/classes/slice.pmc,v
retrieving revision 1.2
retrieving revision 1.3
diff -u -w -r1.2 -r1.3
--- slice.pmc 18 Jun 2004 06:46:23 -0000 1.2
+++ slice.pmc 18 Jun 2004 12:05:59 -0000 1.3
@@ -1,6 +1,6 @@
/*
Copyright: 2004 The Perl Foundation. All Rights Reserved.
-$Id: slice.pmc,v 1.2 2004/06/18 06:46:23 leo Exp $
+$Id: slice.pmc,v 1.3 2004/06/18 12:05:59 leo Exp $
=head1 NAME
@@ -39,8 +39,7 @@
}
}
else {
- /* TODO string */
-
+ PMC_struct_val(self) = key_string(interpreter, range);
}
}
@@ -108,6 +107,21 @@
else
PMC_struct_val(self) = (void *)key_integer(interpreter, range);
}
+ else {
+ if ((PObj_get_FLAGS(range) &
+ (KEY_start_slice_FLAG|KEY_end_slice_FLAG)) ==
+ (KEY_start_slice_FLAG|KEY_end_slice_FLAG)) {
+
+ range = PMC_pmc_val(self) = PMC_data(range);
+ if (!PMC_pmc_val(self))
+ PMC_int_val(self) = -1;
+ else
+ PMC_struct_val(self) = key_string(interpreter, range);
+ }
+ else {
+ internal_exception(1, "slices ranges for hash not implemented");
+ }
+ }
}
pmclass Slice need_ext extends Key {
@@ -118,11 +132,15 @@
return v;
}
+ STRING* get_string() {
+ STRING *s = (STRING *)PMC_struct_val(SELF);
+ return s;
+ }
+
PMC* nextkey_keyed (PMC* agg, INTVAL what) {
PMC *ret = SELF;
PMC *current_key;
- /* printf("Slice_next what = %d\n", (int)what) */;
switch (what) {
case ITERATE_FROM_START:
case ITERATE_FROM_START_KEYS: /* reset key */
1.17 +79 -2 parrot/t/pmc/iter.t
Index: iter.t
===================================================================
RCS file: /cvs/public/parrot/t/pmc/iter.t,v
retrieving revision 1.16
retrieving revision 1.17
diff -u -w -r1.16 -r1.17
--- iter.t 18 Jun 2004 06:46:28 -0000 1.16
+++ iter.t 18 Jun 2004 12:06:06 -0000 1.17
@@ -1,6 +1,6 @@
#! perl -w
# Copyright: 2001-2003 The Perl Foundation. All Rights Reserved.
-# $Id: iter.t,v 1.16 2004/06/18 06:46:28 leo Exp $
+# $Id: iter.t,v 1.17 2004/06/18 12:06:06 leo Exp $
=head1 NAME
@@ -16,7 +16,7 @@
=cut
-use Parrot::Test tests => 23;
+use Parrot::Test tests => 26;
use Test::More qw(skip);
output_is(<<'CODE', <<'OUTPUT', "new iter");
@@ -806,3 +806,80 @@
parrtocks
parrot rocks
OUTPUT
+
+output_is(<<'CODE', <<OUTPUT, "slice iter string variable range");
+ .include "iterator.pasm"
+ new P2, .PerlString
+ set P2, "parrot rocks"
+ set I0, 1
+ set I1, 3
+ set I2, 8
+ set I3, 9
+ slice P1, P2[I0 ..I1 ,5, I2 ..I3]
+ set P1, .ITERATE_FROM_START
+iter_loop:
+ unless P1, iter_end
+ shift S1, P1
+ print S1
+ branch iter_loop
+iter_end:
+ print "\n"
+ print P2
+ print "\n"
+ end
+CODE
+arrtoc
+parrot rocks
+OUTPUT
+
+output_is(<<'CODE', <<OUTPUT, "slice iter hash values");
+ .include "iterator.pasm"
+ new P2, .PerlHash
+ set P2["a"], 100
+ set P2["b"], 200
+ set P2["c"], 300
+ set P2["d"], 400
+ slice P1, P2["b", "c"]
+ set P1, .ITERATE_FROM_START
+iter_loop:
+ unless P1, iter_end
+ shift S1, P1
+ print S1
+ print "\n"
+ branch iter_loop
+iter_end:
+ print "ok\n"
+ end
+CODE
+200
+300
+ok
+OUTPUT
+
+output_is(<<'CODE', <<OUTPUT, "slice iter hash values 2");
+ .include "iterator.pasm"
+ new P2, .PerlHash
+ set P2["a"], 100
+ set P2["b"], 200
+ set P2["c"], 300
+ set P2["d"], 400
+ set P2["e"], 500
+ slice P1, P2["b", "c", "a", "a", "e"]
+ set P1, .ITERATE_FROM_START
+iter_loop:
+ unless P1, iter_end
+ shift S1, P1
+ print S1
+ print "\n"
+ branch iter_loop
+iter_end:
+ print "ok\n"
+ end
+CODE
+200
+300
+100
+100
+500
+ok
+OUTPUT