#!perl
# Copyright (C) 2001-2007, The Perl Foundation.
# $Id: iterator.t 21449 2007-09-21 09:32:00Z paultcochrane $
use strict;
use warnings;
use lib qw( . lib ../lib ../../lib );
use Test::More;
use Parrot::Test tests => 44;
=head1 NAME
t/pmc/iterator.t - Test the Iterator PMC
=head1 SYNOPSIS
% prove t/pmc/iterator.t
=head1 DESCRIPTION
Tests the C<Iterator> PMC.
=cut
pasm_output_is( <<'CODE', <<'OUTPUT', "new iter" );
new P2, 'ResizablePMCArray'
new P1, 'Iterator', P2
print "ok 1\n"
end
CODE
ok 1
OUTPUT
pasm_output_is( <<'CODE', <<'OUTPUT', "int test" );
.include "iterator.pasm"
new P0, 'ResizablePMCArray' # empty array
new P2, 'ResizablePMCArray' # 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, .ITERATE_FROM_START
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, .ITERATE_FROM_START
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, .ITERATE_FROM_END
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
CODE
ok 1
ok 2
ok 3
ok 4
ok 5
ok 6
ok 7
ok 8
ok 9
ok 10
ok 11
ok 12
OUTPUT
pasm_output_is( <<'CODE', <<'OUTPUT', "Hash iter 1" );
.include "iterator.pasm"
new P0, 'Hash' # empty Hash
new P2, 'Hash' # Hash with 2 elements
set P2["ab"], 100
set P2["xy"], "value"
set I0, P2
new P1, 'Iterator', P2
print "ok 1\n"
set I1, P1
eq I0, I1, ok2 # iter.length() == hash.length()
print "not "
ok2: print "ok 2\n"
new P1, 'Iterator', P0
set P1, .ITERATE_FROM_START
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, .ITERATE_FROM_START
if P1, ok5 # if(iter) == true on non empty
print "not "
ok5: print "ok 5\n"
# now iterate over P2
# while (P1) { key = shift(P1) }
unless P1, nok6
shift S3, P1 # get hash.key
eq S3, "ab", ok6
eq S3, "xy", ok6
nok6: print " not "
ok6: print "ok 6\n"
unless P1, nok7
shift S3, P1
eq S3, "ab", ok7
eq S3, "xy", ok7
nok7: print "not "
ok7: print "ok 7\n"
unless P1, ok8 # if(iter) == false after last
print "not "
ok8: print "ok 8\n"
end
CODE
ok 1
ok 2
ok 3
ok 4
ok 5
ok 6
ok 7
ok 8
OUTPUT
pasm_output_is( <<'CODE', <<'OUTPUT', "Hash iter 1" );
.include "iterator.pasm"
new P0, 'Hash' # empty Hash
new P2, 'Hash' # Hash with 2 elements
set P2["ab"], 100
set P2["xy"], "value"
set I0, P2
new P1, 'Iterator', P2
print "ok 1\n"
set I1, P1
eq I0, I1, ok2 # iter.length() == hash.length()
print "not "
ok2: print "ok 2\n"
new P1, 'Iterator', P0
set P1, .ITERATE_FROM_START
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, .ITERATE_FROM_START
if P1, ok5 # if(iter) == true on non empty
print "not "
ok5: print "ok 5\n"
# now iterate over P2
# while (P1) { key = shift(P1) }
unless P1, nok6
shift S3, P1 # get hash.key
eq S3, "ab", ok6
eq S3, "xy", ok6
nok6: print " not "
ok6: print "ok 6\n"
unless P1, nok7
shift S3, P1
eq S3, "ab", ok7
eq S3, "xy", ok7
nok7: print "not "
ok7: print "ok 7\n"
unless P1, ok8 # if(iter) == false after last
print "not "
ok8: print "ok 8\n"
end
CODE
ok 1
ok 2
ok 3
ok 4
ok 5
ok 6
ok 7
ok 8
OUTPUT
pasm_output_is( <<'CODE', <<'OUTPUT', "Hash iter 2" );
.include "iterator.pasm"
new P0, 'Hash' # Hash for iteration
new P2, 'Hash' # for test
set I0, 65
set I1, 35
set I10, I1
fill:
chr S0, I0
set P0[S0], I0
inc I0
dec I1
if I1, fill
new P1, 'Iterator', P0
set I0, P1
eq I0, I10, ok1
print "not "
ok1:
print "ok 1\n"
set P1, .ITERATE_FROM_START
get:
unless P1, done
shift S3, P1 # get hash.key
set I0, P0[S3] # and value
set P2[S3], I0
branch get
done:
set I0, P2
eq I0, I10, ok2
print "not "
ok2:
print "ok 2\n"
end
CODE
ok 1
ok 2
OUTPUT
pasm_output_is( <<'CODE', <<OUTPUT, "string iteration forward" );
.include "iterator.pasm"
new P2, 'String'
set P2, "parrot"
new P1, 'Iterator', P2
set P1, .ITERATE_FROM_START
iter_loop:
unless P1, iter_end # while (entries) ...
shift S1, P1
print S1
branch iter_loop
iter_end:
print "\n"
print P2
print "\n"
end
CODE
parrot
parrot
OUTPUT
pasm_output_is( <<'CODE', <<OUTPUT, "string iteration backward" );
.include "iterator.pasm"
new P2, 'String'
set P2, "parrot"
new P1, 'Iterator', P2
set P1, .ITERATE_FROM_END
iter_loop:
unless P1, iter_end # while (entries) ...
pop S1, P1
print S1
branch iter_loop
iter_end:
print "\n"
print P2
print "\n"
end
CODE
torrap
parrot
OUTPUT
pasm_output_is( <<'CODE', <<OUTPUT, "string iteration forward get ord" );
.include "iterator.pasm"
new P2, 'String'
set P2, "ABC"
new P1, 'Iterator', P2
set P1, .ITERATE_FROM_START
iter_loop:
unless P1, iter_end # while (entries) ...
shift I1, P1
print I1
branch iter_loop
iter_end:
print "\n"
print P2
print "\n"
end
CODE
656667
ABC
OUTPUT
pasm_output_is( <<'CODE', <<OUTPUT, "string iteration backward get ord" );
.include "iterator.pasm"
new P2, 'String'
set P2, "ABC"
new P1, 'Iterator', P2
set P1, .ITERATE_FROM_END
iter_loop:
unless P1, iter_end # while (entries) ...
pop I1, P1
print I1
branch iter_loop
iter_end:
print "\n"
print P2
print "\n"
end
CODE
676665
ABC
OUTPUT
pir_output_is( << 'CODE', << 'OUTPUT', "String iterator in PIR" );
.include "iterator.pasm"
.sub _main
.local pmc string_1
string_1 = new 'String'
string_1 = "abcd\x65\x66\x67"
print string_1
print "\n"
.local pmc iter_1
iter_1 = new 'Iterator', string_1
iter_1 = .ITERATE_FROM_START
.local int code_point_1
ITER_LOOP:
unless iter_1 goto ITER_END
shift code_point_1, iter_1
print code_point_1
print "\n"
branch ITER_LOOP
ITER_END:
print "reached end\n"
end
.end
CODE
abcdefg
97
98
99
100
101
102
103
reached end
OUTPUT
pir_output_is( <<'CODE', <<'OUTPUT', "Index access for Iterator on String" );
.include "iterator.pasm"
.sub _main
.local pmc string_1
string_1 = new 'String'
string_1 = "abcd\x65\x66\x67"
print 'String new: '
print string_1
print "\n"
.local pmc iter_1
iter_1 = new 'Iterator', string_1
iter_1 = .ITERATE_FROM_START
.local int code_point_1
.local num code_point_2
.local string code_point_3
.local pmc code_point_4
print 'Iterator shift_integer: '
shift code_point_1, iter_1
print code_point_1
print "\n"
print 'Iterator get_integer_keyed_int 2: '
code_point_1 = iter_1[2]
print code_point_1
print "\n"
print 'Iterator get_integer_keyed_int 0: '
code_point_1 = iter_1[0]
print code_point_1
print "\n"
print 'Iterator get_integer_keyed_int -1: '
code_point_1 = iter_1[-1]
print code_point_1
print "\n"
end
.end
CODE
String new: abcdefg
Iterator shift_integer: 97
Iterator get_integer_keyed_int 2: 100
Iterator get_integer_keyed_int 0: 98
Iterator get_integer_keyed_int -1: 97
OUTPUT
pir_output_is( << 'CODE', << 'OUTPUT', "Index access for Iterator on ResizablePMCArray" );
.include "iterator.pasm"
.sub _main
.local pmc array_1
array_1 = new 'ResizablePMCArray'
push array_1, 'a'
push array_1, 'b'
push array_1, 'c'
push array_1, 'd'
push array_1, 'e'
push array_1, 'f'
push array_1, '7'
push array_1, '-8.8'
print 'ResizablePMCArray get_string: '
print array_1
print "\n"
.local pmc iter_1
iter_1 = new 'Iterator', array_1
iter_1 = .ITERATE_FROM_START
.local string elem_1
print 'Iterator shift_string: '
shift elem_1, iter_1
print elem_1
print "\n"
print 'Iterator get_string_keyed_int 2: '
elem_1 = iter_1[2]
print elem_1
print "\n"
print 'Iterator get_string_keyed_int -1: '
elem_1 = iter_1[-1]
print elem_1
print "\n"
print 'Iterator get_string_keyed_int 0: '
elem_1 = iter_1[0]
print elem_1
print "\n"
print 'Iterator get_pmc_keyed_int 3: '
.local pmc elem_2
elem_2 = iter_1[3]
print elem_2
print "\n"
.local int flag
print 'Iterator exists_keyed_int 3: '
flag = exists iter_1[3]
print flag
print "\n"
print 'Iterator exists_keyed_int 28: '
flag = exists iter_1[28]
print flag
print "\n"
print 'Iterator defined_keyed_int 3: '
flag = defined iter_1[3]
print flag
print "\n"
print 'Iterator defined_keyed_int -1278: '
flag = defined iter_1[-1278]
print flag
print "\n"
.local pmc iter_2
iter_2 = new 'Iterator', array_1
iter_2 = .ITERATE_FROM_END
print 'Iterator shift_float: '
.local num felem_2
shift felem_2, iter_2
print felem_2
print "\n"
print 'Iterator get_integer: '
.local int elem_3
elem_3 = iter_2[-1]
print elem_3
print "\n"
end
.end
CODE
ResizablePMCArray get_string: 8
Iterator shift_string: a
Iterator get_string_keyed_int 2: d
Iterator get_string_keyed_int -1: a
Iterator get_string_keyed_int 0: b
Iterator get_pmc_keyed_int 3: e
Iterator exists_keyed_int 3: 1
Iterator exists_keyed_int 28: 0
Iterator defined_keyed_int 3: 1
Iterator defined_keyed_int -1278: 0
Iterator shift_float: -8.800000
Iterator get_integer: 7
OUTPUT
SKIP: {
skip( "N/Y: length of rest of array ", 1 );
pasm_output_is( <<'CODE', <<'OUTPUT', "shift + index access" );
.include "iterator.pasm"
new P2, 'ResizablePMCArray' # array with 4 elements
push P2, 10
push P2, 20
push P2, 30
push P2, 40
new P1, 'Iterator', P2
set P1, .ITERATE_FROM_START
set I0, P1 # arr.length
eq I0, 4, ok1
print I0
print " not "
ok1: print "ok 1\n"
shift I0, P1 # get one
eq I0, 10, ok2
print "not "
ok2: print "ok 2\n"
shift I0, P1 # get one
eq I0, 20, ok3
print "not "
ok3: print "ok 3\n"
set I0, P1 # arr.length of rest
eq I0, 2, ok6
print I0
print " not "
ok6: print "ok 6\n"
print P1
end
CODE
ok 1
ok 2
ok 3
ok 6
2
OUTPUT
}
pasm_output_is( <<'CODE', <<'OUTPUT', "slice syntax" );
new P0, 'ResizablePMCArray'
slice P2, P0[2 .. 3, 4, 5 ..6]
slice P2, P0[10 ..]
slice P2, P0[.. 11]
slice P2, P0[I1..3]
new P1, 'Hash'
slice P2, P1["0","a".."b","c"]
print "ok\n"
end
CODE
ok
OUTPUT
pasm_output_is( <<'CODE', <<'OUTPUT', "slice creates an iterator" );
new P0, 'ResizablePMCArray'
slice P2, P0[2 .. 3, 4, 5 ..6]
typeof S0, P2
print S0
print "\n"
end
CODE
Iterator
OUTPUT
pasm_output_is( <<'CODE', <<'OUTPUT', "slice iter simple array elements" );
.include "iterator.pasm"
new P0, 'ResizablePMCArray'
push P0, 100
push P0, 200
push P0, 300
push P0, 400
push P0, 500
push P0, 600
slice P2, P0[0, 1, 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
500
ok
OUTPUT
pasm_output_is( <<'CODE', <<'OUTPUT', "slice iter simple array elements - repeat" );
.include "iterator.pasm"
new P0, 'ResizablePMCArray'
push P0, 100
push P0, 200
push P0, 300
push P0, 400
push P0, 500
slice P2, P0[2, 4]
set P2, .ITERATE_FROM_START
lp:
unless P2, ex
shift I0, P2
print I0
print "\n"
branch lp
ex:
slice P2, P0[2, 4] # this is the same PF constant
set P2, .ITERATE_FROM_START
lp2:
unless P2, ex2
shift I0, P2
print I0
print "\n"
branch lp2
ex2:
print "ok\n"
end
CODE
300
500
300
500
ok
OUTPUT
pasm_output_is( <<'CODE', <<OUTPUT, "slice iter string" );
.include "iterator.pasm"
new P2, 'String'
set P2, "parrot"
slice P1, P2[0,1,4,5]
set P1, .ITERATE_FROM_START
iter_loop:
unless P1, iter_end # while (entries) ...
shift S1, P1
print S1
branch iter_loop
iter_end:
print "\n"
print P2
print "\n"
end
CODE
paot
parrot
OUTPUT
pasm_output_is( <<'CODE', <<'OUTPUT', "slice iter start range" );
.include "iterator.pasm"
new P0, 'ResizablePMCArray'
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
pasm_output_is( <<'CODE', <<'OUTPUT', "slice iter end range" );
.include "iterator.pasm"
new P0, 'ResizablePMCArray'
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
300
400
500
ok
OUTPUT
pasm_output_is( <<'CODE', <<'OUTPUT', "slice iter start range, value" );
.include "iterator.pasm"
new P0, 'ResizablePMCArray'
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
pasm_output_is( <<'CODE', <<'OUTPUT', "slice iter range, value" );
.include "iterator.pasm"
new P0, 'ResizablePMCArray'
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
pasm_output_is( <<'CODE', <<'OUTPUT', "slice iter range, range" );
.include "iterator.pasm"
new P0, 'ResizablePMCArray'
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
pasm_output_is( <<'CODE', <<OUTPUT, "slice iter string range" );
.include "iterator.pasm"
new P2, 'String'
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
pasm_output_is( <<'CODE', <<OUTPUT, "slice iter string range 2" );
.include "iterator.pasm"
new P2, 'String'
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
pasm_output_is( <<'CODE', <<OUTPUT, "slice iter string variable range" );
.include "iterator.pasm"
new P2, 'String'
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
pasm_output_is( <<'CODE', <<OUTPUT, "slice iter hash values" );
.include "iterator.pasm"
new P2, 'Hash'
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
pasm_output_is( <<'CODE', <<OUTPUT, "slice iter hash values 2" );
.include "iterator.pasm"
new P2, 'Hash'
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
pasm_output_is( <<'CODE', <<OUTPUT, "slice iter range" );
.include "iterator.pasm"
new P2, 'Hash'
set P2["a"], 10
set P2["b"], 20
set P2["c"], 30
set P2["d"], 40
set P2["e"], 50
slice P1, P2["a".. "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
10
20
30
ok
OUTPUT
pasm_output_is( <<'CODE', <<OUTPUT, "slice iter range 2" );
.include "iterator.pasm"
new P2, 'Hash'
set P2["a"], 10
set P2["b"], 20
set P2["c"], 30
set P2["d"], 40
set P2["e"], 50
set P2["A"], 11
set P2["B"], 21
set P2["C"], 31
set P2["D"], 41
set P2["E"], 51
slice P1, P2["a".. "c", 'C' .. '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
10
20
30
31
41
51
ok
OUTPUT
pasm_output_is( <<'CODE', <<OUTPUT, "slice iter range - vars" );
.include "iterator.pasm"
new P2, 'Hash'
set P2["a"], 10
set P2["b"], 20
set P2["c"], 30
set P2["d"], 40
set P2["e"], 50
set P2["A"], 11
set P2["B"], 21
set P2["C"], 31
set P2["D"], 41
set P2["E"], 51
set S0, 'a'
set S1, 'c'
set S2, 'C'
set S3, 'E'
slice P1, P2[S0 .. S1, S2 .. S3, 'A']
set P1, .ITERATE_FROM_START
iter_loop:
unless P1, iter_end
shift S10, P1
print S10
print "\n"
branch iter_loop
iter_end:
print "ok\n"
end
CODE
10
20
30
31
41
51
11
ok
OUTPUT
pir_output_is( <<'CODE', <<'OUTPUT', "xrange iterator" );
.sub main
.include "iterator.pasm"
# xrange(10, 14)
new P2, 'Slice' [10 .. 14]
new P1, 'Iterator', P2
set P1, .ITERATE_FROM_START
# I0 = P1."len"()
iter_loop:
unless P1, iter_end
shift I1, P1
print I1
print "\n"
branch iter_loop
iter_end:
print "ok\n"
end
.end
CODE
10
11
12
13
ok
OUTPUT
pir_output_is( <<'CODE', <<'OUTPUT', "xrange iterator ..n" );
.sub main
.include "iterator.pasm"
# xrange(4)
new P2, 'Slice' [ .. 4]
new P1, 'Iterator', P2
set P1, .ITERATE_FROM_START
# I0 = P1."len"()
iter_loop:
unless P1, iter_end
shift I1, P1
print I1
print "\n"
branch iter_loop
iter_end:
print "ok\n"
end
.end
CODE
0
1
2
3
ok
OUTPUT
pir_output_is( <<'CODE', <<'OUTPUT', "slice, get strings from array" );
.sub main :main
.include "iterator.pasm"
.local pmc ar
ar = new 'ResizablePMCArray'
push ar, "a"
push ar, "b"
push ar, "c"
push ar, "d"
push ar, "e"
.local pmc iter
iter = slice ar[1 ..]
iter = .ITERATE_FROM_START
iter_loop:
unless iter, iter_end # while (entries) ...
$S0 = shift iter
print $S0
goto iter_loop
iter_end:
print "ok\n"
.end
CODE
bcdeok
OUTPUT
pasm_output_is( <<'CODE', <<'OUTPUT', "iter vtable" );
.include "iterator.pasm"
new P0, 'ResizablePMCArray'
push P0, 100
push P0, 200
push P0, 300
push P0, 400
push P0, 500
push P0, 600
push P0, 700
push P0, 800
iter P2, P0
print "ok 1\n"
lp:
unless P2, ex
shift I0, P2
print I0
print "\n"
branch lp
ex:
print "ok 2\n"
end
CODE
ok 1
100
200
300
400
500
600
700
800
ok 2
OUTPUT
pasm_output_is( <<'CODE', <<OUTPUT, "string iteration with get_iter" );
.include "iterator.pasm"
new P2, 'String'
set P2, "parrot"
iter P1, P2
iter_loop:
unless P1, iter_end # while (entries) ...
shift S1, P1
print S1
branch iter_loop
iter_end:
print "\n"
print P2
print "\n"
end
CODE
parrot
parrot
OUTPUT
pasm_output_is( <<'CODE', <<'OUTPUT', "intlist iter vtable" );
.include "iterator.pasm"
new P0, 'IntList'
push P0, 100
push P0, 200
push P0, 300
push P0, 400
push P0, 500
push P0, 600
push P0, 700
push P0, 800
iter P2, P0
print "ok 1\n"
lp:
unless P2, ex
shift I0, P2
print I0
print "\n"
branch lp
ex:
print "ok 2\n"
end
CODE
ok 1
100
200
300
400
500
600
700
800
ok 2
OUTPUT
pir_output_is( <<'CODE', <<'OUTPUT', 'xrange iterator, get_iter' );
.sub main
.include "iterator.pasm"
# xrange(10, 14)
new P2, 'Slice' [10 .. 14]
P1 = iter P2
# I0 = P1."len"()
iter_loop:
unless P1, iter_end
shift I1, P1
print I1
print "\n"
branch iter_loop
iter_end:
print "ok\n"
end
.end
CODE
10
11
12
13
ok
OUTPUT
TODO: {
local $TODO = "adding keys during iteration";
pir_output_is( << 'CODE', << 'OUTPUT', "adding keys during iteration" );
.sub main :main
.local pmc h, it, ar
.local string k
.local int i,v
h = new 'Hash'
i = 0
lp1:
$I0 = i + 65
k = chr $I0
h[k] = i
inc i
if i < 10 goto lp1
it = iter h
ar = new 'ResizablePMCArray'
i = 20
lp2:
unless it goto ex
k = shift it
v = h[k]
push ar, v
if i == 29 goto no_add
$I0 = i + 65
k = chr $I0
h[k] = i
inc i
no_add:
goto lp2
ex:
ar."sort"()
i = elements ar
lp3:
dec i
v = ar[i]
print v
print "_"
if i goto lp3
print "\n"
.end
# or some such output
CODE
29_28_27_26_25_24_23_22_21_20_9_8_7_6_5_4_3_2_1_0_
OUTPUT
}
pir_output_is( << 'CODE', << 'OUTPUT', "by default, iterate from start" );
.sub main :main
.local pmc ar, it
ar= new 'ResizablePMCArray'
push ar, 'pi'
push ar, 3
push ar, 6.28
it = iter ar
lp: unless it, ex
$P0 = shift it
print $P0
print "\n"
branch lp
ex:
.end
CODE
pi
3
6.28
OUTPUT
pir_output_is( << 'CODE', << 'OUTPUT', "iterator can be cloned" );
.sub main :main
.local pmc ar, i1, i2
ar = new 'ResizableIntegerArray'
push ar, 17
new i1, 'Iterator', ar
clone i2, i1
.end
CODE
OUTPUT
pir_output_is( << 'CODE', << 'OUTPUT', "cloned iterator independent of original" );
.sub main :main
.local pmc ar, i1, i2
ar = new 'ResizableIntegerArray'
push ar, 17
push ar, 42
new i1, 'Iterator', ar
clone i2, i1
.local Integer temp
shift temp, i1
unless temp == 17 goto fail
shift temp, i1
unless temp == 42 goto fail
shift temp, i2
unless temp == 17 goto fail
shift temp, i2
unless temp == 42 goto fail
say "ok"
end
fail:
say "not ok"
.end
CODE
ok
OUTPUT
pir_output_is( <<'CODE', <<'OUTPUT', "clone of partly-advanced iterator" );
.sub main :main
.local pmc ar, i1, i2
.local Integer temp
ar = new 'ResizableIntegerArray'
push ar, 1
push ar, 2
new i1, 'Iterator', ar
shift temp, i1
unless temp == 1 goto fail
clone i2, i1
shift temp, i1
unless temp == 2 goto fail
shift temp, i2
unless temp == 2 goto fail
say "ok"
end
fail:
say "not ok"
.end
CODE
ok
OUTPUT
TODO: {
local $TODO = "cloned iterator doesn't copy the array to which it 'points'";
pir_output_is(
<<'CODE', <<'OUTPUT', "cloned iterator doesn't copy the array to which it 'points'" );
.sub main :main
.local pmc ar, i1, i2
.local Integer temp
temp = new 'Integer'
ar = new 'ResizableIntegerArray'
push ar, 1
new i1, 'Iterator', ar
# i1 and i2 now "point" to the same element of the same array.
clone i2, i1
# Modify the array ...
temp = 17
i1 = temp
# Now read back the modified value ...
shift temp, i2
unless temp == 17 goto fail
say "ok"
end
fail:
say "not ok"
.end
CODE
ok
OUTPUT
}
# Local Variables:
# mode: cperl
# cperl-indent-level: 4
# fill-column: 100
# End:
# vim: expandtab shiftwidth=4:
syntax highlighted by Code2HTML, v. 0.9.1