cvsuser 04/06/17 23:46:28
Modified: classes perlstring.pmc slice.pmc
t/pmc iter.t
Log:
slices 6 - ranges for array, perlstring
Revision Changes Path
1.73 +1 -6 parrot/classes/perlstring.pmc
Index: perlstring.pmc
===================================================================
RCS file: /cvs/public/parrot/classes/perlstring.pmc,v
retrieving revision 1.72
retrieving revision 1.73
diff -u -w -r1.72 -r1.73
--- perlstring.pmc 17 Jun 2004 16:30:19 -0000 1.72
+++ perlstring.pmc 18 Jun 2004 06:46:23 -0000 1.73
@@ -1,6 +1,6 @@
/*
Copyright: 2001-2003 The Perl Foundation. All Rights Reserved.
-$Id: perlstring.pmc,v 1.72 2004/06/17 16:30:19 leo Exp $
+$Id: perlstring.pmc,v 1.73 2004/06/18 06:46:23 leo Exp $
=head1 NAME
@@ -689,11 +689,6 @@
ret = VTABLE_nextkey_keyed(interpreter, key, SELF, what);
- if (PMC_int_val(ret) > 0)
- PMC_data(key) = string_pointer_to_index(INTERP, s,
- PMC_int_val(ret));
- /* else do what? */
-
return ret;
}
1.2 +95 -11 parrot/classes/slice.pmc
Index: slice.pmc
===================================================================
RCS file: /cvs/public/parrot/classes/slice.pmc,v
retrieving revision 1.1
retrieving revision 1.2
diff -u -w -r1.1 -r1.2
--- slice.pmc 17 Jun 2004 18:27:50 -0000 1.1
+++ slice.pmc 18 Jun 2004 06:46:23 -0000 1.2
@@ -1,6 +1,6 @@
/*
Copyright: 2004 The Perl Foundation. All Rights Reserved.
-$Id: slice.pmc,v 1.1 2004/06/17 18:27:50 leo Exp $
+$Id: slice.pmc,v 1.2 2004/06/18 06:46:23 leo Exp $
=head1 NAME
@@ -20,12 +20,100 @@
#include "parrot/parrot.h"
+static void
+set_slice_start(Interp *interpreter, PMC *self)
+{
+ PMC* range = PMC_pmc_val(self);
+
+ /*
+ * and start value in struct_val
+ */
+ if (key_type(interpreter, range) & KEY_integer_FLAG) {
+ /* integer key */
+ if (PObj_get_FLAGS(range) & KEY_inf_slice_FLAG) {
+ /* first range is ".. end" */
+ PMC_struct_val(self) = (void *)0;
+ }
+ else {
+ PMC_struct_val(self) = (void *)key_integer(interpreter, range);
+ }
+ }
+ else {
+ /* TODO string */
+
+ }
+}
+
+static void
+set_slice_next(Interp *interpreter, PMC *self, PMC *agg)
+{
+ PMC* range = PMC_pmc_val(self);
+ INTVAL cur, end;
+
+ if (key_type(interpreter, range) & KEY_integer_FLAG) {
+ if ((PObj_get_FLAGS(range) &
+ (KEY_start_slice_FLAG|KEY_end_slice_FLAG)) ==
+ (KEY_start_slice_FLAG|KEY_end_slice_FLAG)) {
+ /* start = end, single element */
+ goto next_range;
+ }
+ if ((PObj_get_FLAGS(range) &
+ (KEY_inf_slice_FLAG|KEY_end_slice_FLAG)) ==
+ (KEY_inf_slice_FLAG|KEY_end_slice_FLAG)) {
+ /* first range is ".. end" */
+ cur = (INTVAL)PMC_struct_val(self);
+ end = key_integer(interpreter, range);
+ if (cur < end) {
+ ++cur;
+ PMC_struct_val(self) = (void *)cur;
+ return;
+ }
+ goto next_range;
+ }
+
+ if ((PObj_get_FLAGS(range) &
+ (KEY_inf_slice_FLAG|KEY_start_slice_FLAG)) ==
+ (KEY_inf_slice_FLAG|KEY_start_slice_FLAG)) {
+ /* last range "start .." */
+ cur = (INTVAL)PMC_struct_val(self);
+ end = VTABLE_elements(interpreter, agg);
+ if (cur < end - 1) {
+ ++cur;
+ PMC_struct_val(self) = (void *)cur;
+ return;
+ }
+ goto next_range;
+ }
+ if (PObj_get_FLAGS(range) & KEY_start_slice_FLAG) {
+ PMC *end_range = PMC_data(range);
+ if (!end_range)
+ internal_exception(1, "No end range found");
+ cur = (INTVAL)PMC_struct_val(self);
+ end = key_integer(interpreter, end_range);
+ if (cur < end) {
+ ++cur;
+ PMC_struct_val(self) = (void *)cur;
+ return;
+ }
+ /* skip end range */
+ PMC_pmc_val(self) = end_range;
+ range = end_range;
+ /* go on with next_range */
+ }
+
+next_range:
+ range = PMC_pmc_val(self) = PMC_data(range);
+ if (!PMC_pmc_val(self))
+ PMC_int_val(self) = -1;
+ else
+ PMC_struct_val(self) = (void *)key_integer(interpreter, range);
+ }
+}
+
pmclass Slice need_ext extends Key {
INTVAL get_integer() {
- PMC *key = PMC_pmc_val(SELF);
- /* TODO check range */
- INTVAL v = key_integer(INTERP, key);
+ INTVAL v = (INTVAL)PMC_struct_val(SELF);
/* printf("Slice_get_integer %d\n", (int)v); */
return v;
}
@@ -46,19 +134,15 @@
PObj_get_FLAGS(ret) &= ~KEY_type_FLAGS;
PObj_get_FLAGS(ret) |= KEY_pmc_FLAG;
- PMC_struct_val(ret) = NULL;
PMC_data(ret) = NULL;
/*
- * key_pmc needs this
+ * remember slice chain in PMC_pmc_val
*/
PMC_pmc_val(ret) = SELF;
+ set_slice_start(INTERP, ret);
break;
case ITERATE_GET_NEXT:
- current_key = PMC_pmc_val(SELF);
- /* TODO check range */
- PMC_pmc_val(SELF) = PMC_data(current_key);
- if (!PMC_pmc_val(SELF))
- PMC_int_val(SELF) = -1;
+ set_slice_next(INTERP, ret, agg);
break;
}
return ret;
1.16 +158 -2 parrot/t/pmc/iter.t
Index: iter.t
===================================================================
RCS file: /cvs/public/parrot/t/pmc/iter.t,v
retrieving revision 1.15
retrieving revision 1.16
diff -u -w -r1.15 -r1.16
--- iter.t 17 Jun 2004 16:30:28 -0000 1.15
+++ iter.t 18 Jun 2004 06:46:28 -0000 1.16
@@ -1,6 +1,6 @@
#! perl -w
# Copyright: 2001-2003 The Perl Foundation. All Rights Reserved.
-# $Id: iter.t,v 1.15 2004/06/17 16:30:28 leo Exp $
+# $Id: iter.t,v 1.16 2004/06/18 06:46:28 leo Exp $
=head1 NAME
@@ -16,7 +16,7 @@
=cut
-use Parrot::Test tests => 17;
+use Parrot::Test tests => 23;
use Test::More qw(skip);
output_is(<<'CODE', <<'OUTPUT', "new iter");
@@ -650,3 +650,159 @@
parrot
OUTPUT
+output_is(<<'CODE', <<'OUTPUT', "slice iter start range");
+ .include "iterator.pasm"
+ new P0, .PerlArray
+ push P0, 100
+ push P0, 200
+ push P0, 300
+ push P0, 400
+ push P0, 500
+ slice P2, P0[..2]
+ set P2, .ITERATE_FROM_START
+lp:
+ unless P2, ex
+ shift I0, P2
+ print I0
+ print "\n"
+ branch lp
+ex:
+ print "ok\n"
+ end
+CODE
+100
+200
+300
+ok
+OUTPUT
+
+output_is(<<'CODE', <<'OUTPUT', "slice iter start range, value");
+ .include "iterator.pasm"
+ new P0, .PerlArray
+ push P0, 100
+ push P0, 200
+ push P0, 300
+ push P0, 400
+ push P0, 500
+ push P0, 600
+ slice P2, P0[..2, 4]
+ set P2, .ITERATE_FROM_START
+lp:
+ unless P2, ex
+ shift I0, P2
+ print I0
+ print "\n"
+ branch lp
+ex:
+ print "ok\n"
+ end
+CODE
+100
+200
+300
+500
+ok
+OUTPUT
+
+output_is(<<'CODE', <<'OUTPUT', "slice iter range, value");
+ .include "iterator.pasm"
+ new P0, .PerlArray
+ push P0, 100
+ push P0, 200
+ push P0, 300
+ push P0, 400
+ push P0, 500
+ push P0, 600
+ push P0, 700
+ slice P2, P0[1 ..3,6]
+ set P2, .ITERATE_FROM_START
+lp:
+ unless P2, ex
+ shift I0, P2
+ print I0
+ print "\n"
+ branch lp
+ex:
+ print "ok\n"
+ end
+CODE
+200
+300
+400
+700
+ok
+OUTPUT
+
+output_is(<<'CODE', <<'OUTPUT', "slice iter range, range");
+ .include "iterator.pasm"
+ new P0, .PerlArray
+ push P0, 100
+ push P0, 200
+ push P0, 300
+ push P0, 400
+ push P0, 500
+ push P0, 600
+ push P0, 700
+ push P0, 800
+ slice P2, P0[1 ..3, 5 ..]
+ set P2, .ITERATE_FROM_START
+lp:
+ unless P2, ex
+ shift I0, P2
+ print I0
+ print "\n"
+ branch lp
+ex:
+ print "ok\n"
+ end
+CODE
+200
+300
+400
+600
+700
+800
+ok
+OUTPUT
+
+output_is(<<'CODE', <<OUTPUT, "slice iter string range");
+ .include "iterator.pasm"
+ new P2, .PerlString
+ set P2, "parrot rocks"
+ slice P1, P2[1 ..3 ,5, 8 ..9]
+ 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 string range 2");
+ .include "iterator.pasm"
+ new P2, .PerlString
+ set P2, "parrot rocks"
+ slice P1, P2[ ..3 ,5, 8 ..]
+ 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
+parrtocks
+parrot rocks
+OUTPUT