* src/pmc/scalar.pmc:
[parrot.git] / t / pmc / resizablebooleanarray.t
blob045a77a690cfacdd6b9bb96e74ff659f160170b8
1 #! perl
2 # Copyright (C) 2001-2005, The Perl Foundation.
3 # $Id$
5 use strict;
6 use warnings;
7 use lib qw( . lib ../lib ../../lib );
8 use Test::More;
9 use Parrot::Test tests => 20;
11 =head1 NAME
13 t/pmc/resizablebooleanarray.t - testing the ResizableBooleanArray PMC
15 =head1 SYNOPSIS
17     % prove t/pmc/resizablebooleanarray.t
19 =head1 DESCRIPTION
21 Tests C<ResizableBooleanArray> PMC. Checks size, sets various elements, including
22 out-of-bounds test. Checks INT and PMC keys.
24 =cut
26 my $fp_equality_macro = <<'ENDOFMACRO';
27 .macro fp_eq (  J, K, L )
28         save    N0
29         save    N1
30         save    N2
32         set     N0, .J
33         set     N1, .K
34         sub     N2, N1,N0
35         abs     N2, N2
36         gt      N2, 0.000001, .$FPEQNOK
38         restore N2
39         restore N1
40         restore N0
41         branch  .L
42 .local $FPEQNOK:
43         restore N2
44         restore N1
45         restore N0
46 .endm
47 .macro fp_ne(   J,K,L)
48         save    N0
49         save    N1
50         save    N2
52         set     N0, .J
53         set     N1, .K
54         sub     N2, N1,N0
55         abs     N2, N2
56         lt      N2, 0.000001, .$FPNENOK
58         restore N2
59         restore N1
60         restore N0
61         branch  .L
62 .local $FPNENOK:
63         restore N2
64         restore N1
65         restore N0
66 .endm
67 ENDOFMACRO
69 pasm_output_is( <<'CODE', <<'OUTPUT', "Setting array size" );
70         new P0, .ResizableBooleanArray
72         set I0,P0
73         eq I0,0,OK_1
74         print "not "
75 OK_1:   print "ok 1\n"
77         set P0,1
78         set I0,P0
79         eq I0,1,OK_2
80         print "not "
81 OK_2:   print "ok 2\n"
83         set P0,5
84         set I0,P0
85         eq I0,5,OK_3
86         print "not "
87 OK_3:   print "ok 3\n"
88         
89         set P0,50
90         set I0,P0
91         eq I0,50,OK_4
92         print "not "
93 OK_4:   print "ok 4\n"
94         
95         set P0,7
96         set I0,P0
97         eq I0,7,OK_5
98         print "not "
99 OK_5:   print "ok 5\n"
100         end
101 CODE
102 ok 1
103 ok 2
104 ok 3
105 ok 4
106 ok 5
107 OUTPUT
109 pasm_output_is( <<'CODE', <<'OUTPUT', "Setting first element" );
110         new P0, .ResizableBooleanArray
111         set P0, 1
113         set P0[0],-7
114         set I0,P0[0]
115         eq I0,1,OK_1
116         print "not "
117 OK_1:   print "ok 1\n"
119         set P0[0],3.7
120         set N0,P0[0]
121         eq N0,1.0,OK_2
122         print "not "
123 OK_2:   print "ok 2\n"
125         set P0[0],"17"
126         set S0,P0[0]
127         eq S0,"1",OK_3
128         print "not "
129 OK_3:   print "ok 3\n"
131         end
132 CODE
133 ok 1
134 ok 2
135 ok 3
136 OUTPUT
138 pasm_output_is( <<'CODE', <<'OUTPUT', "Setting second element" );
139         new P0, .ResizableBooleanArray
140         set P0, 2
142         set P0[1], -7
143         set I0, P0[1]
144         eq I0,1,OK_1
145         print "not "
146 OK_1:   print "ok 1\n"
148         set P0[1], 3.7
149         set N0, P0[1]
150         eq N0,1.0,OK_2
151         print "not "
152 OK_2:   print "ok 2\n"
154         set P0[1],"17"
155         set S0, P0[1]
156         eq S0,"1",OK_3
157         print "not "
158 OK_3:   print "ok 3\n"
160         end
161 CODE
162 ok 1
163 ok 2
164 ok 3
165 OUTPUT
167 # TODO: Rewrite these properly when we have exceptions
169 pasm_output_is( <<'CODE', <<'OUTPUT', "Setting out-of-bounds elements" );
170         new P0, .ResizableBooleanArray
172         set P0[1], -7
173         set I0, P0[1]
174         eq I0,1,OK_1
175         print "not "
176 OK_1:   print "ok 1\n"
178         set P0[0], 3.7
179         set N0, P0[0]
180         eq N0,1.0,OK_2
181         print "not "
182 OK_2:   print "ok 2\n"
184         set P0[5],"17"
185         set S0, P0[5]
186         eq S0,"1",OK_3
187         print "not "
188 OK_3:   print "ok 3\n"
190         end
191 CODE
192 ok 1
193 ok 2
194 ok 3
195 OUTPUT
197 pasm_output_is( <<'CODE', <<'OUTPUT', "Getting out-of-bounds elements" );
198         new P0, .ResizableBooleanArray
199         set P0, 1
201         set I0, P0[1]
202         print "ok 1\n"
203         end
204 CODE
205 ok 1
206 OUTPUT
208 pasm_output_is( <<"CODE", <<'OUTPUT', "Set via PMC keys, access via INTs" );
209 @{[ $fp_equality_macro ]}
210      new P0, .ResizableBooleanArray
211      new P1, .Key
213      set P1, 0
214      set P0[P1], 25
216      set P1, 1
217      set P0[P1], 2.5
219      set P1, 2
220      set P0[P1], "17"
222      set I0, P0[0]
223      eq I0, 1, OK1
224      print "not "
225 OK1: print "ok 1\\n"
227      set N0, P0[1]
228      .fp_eq(N0, 1.0, OK2)
229      print "not "
230 OK2: print "ok 2\\n"
232      set S0, P0[2]
233      eq S0, "1", OK3
234      print "not "
235 OK3: print "ok 3\\n"
237      end
238 CODE
239 ok 1
240 ok 2
241 ok 3
242 OUTPUT
244 pasm_output_is( <<"CODE", <<'OUTPUT', "Set via INTs, access via PMC Keys" );
245 @{[ $fp_equality_macro ]}
246      new P0, .ResizableBooleanArray
247      set P0, 1
249      set P0[25], 125
250      set P0[128], 10.2
251      set P0[513], "17"
252      new P1, .Integer
253      set P1, 123456
254      set P0[1023], P1
256      new P2, .Key
257      set P2, 25
258      set I0, P0[P2]
259      eq I0, 1, OK1
260      print "not "
261 OK1: print "ok 1\\n"
263      set P2, 128
264      set N0, P0[P2]
265      .fp_eq(N0, 1.0, OK2)
266      print "not "
267 OK2: print "ok 2\\n"
269      set P2, 513
270      set S0, P0[P2]
271      eq S0, "1", OK3
272      print "not "
273 OK3: print "ok 3\\n"
275      set P2, 1023
276      set P3, P0[P2]
277      set I1, P3
278      eq I1, 1, OK4
279      print "not "
280 OK4: print "ok 4\\n"
282      end
283 CODE
284 ok 1
285 ok 2
286 ok 3
287 ok 4
288 OUTPUT
290 pir_output_is( << 'CODE', << 'OUTPUT', "check whether interface is done" );
291 .sub _main
292     .local pmc pmc1
293     pmc1 = new ResizableBooleanArray
294     .local int bool1
295     does bool1, pmc1, "scalar"
296     print bool1
297     print "\n"
298     does bool1, pmc1, "array"
299     print bool1
300     print "\n"
301     does bool1, pmc1, "no_interface"
302     print bool1
303     print "\n"
304     end
305 .end
306 CODE
310 OUTPUT
312 pir_output_is( << 'CODE', << 'OUTPUT', "push integer" );
313 .sub _main
314     .local pmc pmc1
315     pmc1 = new ResizableBooleanArray
316     pmc1[9999] = 0
317     push pmc1, 10001
318     .local int elements
319     elements = pmc1
320     print elements
321     print "\n"
322     .local string last
323     last = pmc1[10000]
324     print last
325     print "\n"
326     end
327 .end
328 CODE
329 10001
331 OUTPUT
333 pasm_output_is( <<'CODE', <<'OUTPUT', "creation" );
334         new P0, .ResizableBooleanArray
335         set I0, P0
336         print "Created ResizableBooleanArray with "
337         print I0
338         print " elements to start with.\n"
339         end
340 CODE
341 Created ResizableBooleanArray with 0 elements to start with.
342 OUTPUT
344 pir_output_is( << 'CODE', << 'OUTPUT', "push and pop" );
345 .sub test :main
346        .local int i, i_elem
347        .local pmc pmc_arr
348        .local int elements
350        i = 1
351        pmc_arr = new ResizableBooleanArray
353        print_num_elements( pmc_arr )
355        push pmc_arr, i
356        print i
357        print_num_elements( pmc_arr )
359        push pmc_arr, 0
360        print 0
361        print_num_elements( pmc_arr )
363        print_num_elements( pmc_arr )
365        i_elem= pop pmc_arr
366        print i_elem
367        print_num_elements( pmc_arr )
369        i_elem= pop pmc_arr
370        print i_elem
371        print_num_elements( pmc_arr )
373     pmc_arr = 62
374     push pmc_arr, 0
375     push pmc_arr, 1
376     push pmc_arr, 0
377     push pmc_arr, 1
378     i_elem = pop pmc_arr
379     i_elem = pop pmc_arr
380     i_elem = pop pmc_arr
381     print i_elem
382     print_num_elements(pmc_arr)
383 .end
385 .sub print_num_elements
386        .param pmc pmc_arr
387        .local int elements
388        elements= pmc_arr
389        print '['
390        print elements
391        print "]\n"
392        .return()
393 .end
395 CODE
397 1[1]
398 0[2]
400 0[1]
401 1[0]
402 1[63]
403 OUTPUT
405 pir_output_like( << 'CODE', << 'OUTPUT', "pop bounds checking" );
406 .sub 'test' :main
407        P0 = new .ResizableBooleanArray
408        pop I0, P0
409 .end
410 CODE
411 /ResizableBooleanArray: Can't pop from an empty array!.*/
412 OUTPUT
416 pir_output_is( << 'CODE', << 'OUTPUT', "unshift and shift" );
417 .sub test :main
418        .local int i, i_elem
419        .local pmc pmc_arr
420        .local int elements
422        i= 1
423        pmc_arr = new ResizableBooleanArray
425        # No elements are set
426        print_num_elements( pmc_arr )
428        # Set two of the first three elements
429        pmc_arr[0] = 1
430        pmc_arr[2] = 1
431        print_num_elements( pmc_arr )
433        # Unshift a "1"  element on
434        unshift pmc_arr, i
435        print i
436        print_num_elements( pmc_arr )
438        # Unshift a "0"  element on
439        unshift pmc_arr, 0
440        print 0
441        print_num_elements( pmc_arr )
443        # Shift an element off
444        i_elem= shift pmc_arr
445        print i_elem
446        print_num_elements( pmc_arr )
448        # Shift an element off
449        i_elem= shift pmc_arr
450        print i_elem
451        print_num_elements( pmc_arr )
453        # Resize the array
454        pmc_arr = 62
455        print_num_elements(pmc_arr)
457        # Unshift 4 elements on
458        unshift pmc_arr, 1
459        unshift pmc_arr, 1
460        unshift pmc_arr, 0
461        unshift pmc_arr, 1
462        print_num_elements(pmc_arr)
464        # Shift 3 elements off
465        i_elem = shift pmc_arr
466        i_elem = shift pmc_arr
467        i_elem = shift pmc_arr
468        print i_elem
469        print_num_elements(pmc_arr)
471        # Set same size array is currently
472        pmc_arr = 63
473        print_num_elements(pmc_arr)
475        # Set 101th element
476        pmc_arr[100] = 1
477        print_num_elements(pmc_arr)
479        # Shift off 99 elements
480       .local int counter
481       counter = 98
482 shift_loop:
483        i_elem = shift pmc_arr
484        dec counter
485        if counter > 0 goto shift_loop
487        print i_elem
488        print_num_elements(pmc_arr)
489 .end
491 .sub print_num_elements
492        .param pmc pmc_arr
493        .local int elements
494        elements= pmc_arr
495        print '['
496        print elements
497        print "]\n"
498        $I0 = pmc_arr[0]
499        print $I0
500        print ', '
501        $I0 = pmc_arr[1]
502        print $I0
503        print ', '
504        $I0 = pmc_arr[2]
505        print $I0
506        print "\n"
507        .return()
508 .end
510 CODE
512 0, 0, 0
514 1, 0, 1
515 1[4]
516 1, 1, 0
517 0[5]
518 0, 1, 1
519 0[4]
520 1, 1, 0
521 1[3]
522 1, 0, 1
523 [62]
524 1, 0, 1
525 [66]
526 1, 0, 1
527 1[63]
528 1, 1, 0
529 [63]
530 1, 1, 0
531 [101]
532 1, 1, 0
533 0[3]
534 0, 0, 1
535 OUTPUT
537 pir_output_like( << 'CODE', << 'OUTPUT', "shift bounds checking" );
538 .sub 'test' :main
539        P0 = new .ResizableBooleanArray
540        shift I0, P0
541 .end
542 CODE
543 /ResizableBooleanArray: Can't shift from an empty array!.*/
544 OUTPUT
548 pasm_output_is( <<'CODE', <<'OUTPUT', "aerobics" );
549         new P0, .ResizableBooleanArray
550         set I10, 10000
552         set I1, 0
553         set I0, 0
554 buildup:
555         ge I0, I10, postBuildUp
557         mod I4, I1, 2
558         push P0, I4
559         add I1, 1    # Push P0, mod I1++, 2
560         mod I4, I1, 2
561         push P0, I4
562         add I1, 1    # Push P0, mod I1++, 2
563         mod I4, I1, 2
564         push P0, I4
565         add I1, 1    # Push P0, mod I1++, 2
567         pop I2, P0
568         mul I3, I0, 3
569         add I3, 2
570         mod I3, 2
571         ne I2, I3, errFirstPop  # fail if pop != mod I0 * 3 + 2, 2
573         pop I2, P0
574         mul I3, I0, 3
575         add I3, 1
576         mod I3, 2
577         ne I2, I3, errSecondPop  # fail if pop != mod I0 * 3 + 1, 2
579         set I2, P0
580         add I3, I0, 1
581         ne I2, I3, errBuildLen   # fail if length != I0 + 1
583         add I0, 1
584         branch buildup
585 postBuildUp:
587         set I0, 0
588 checkBuildUpLeft:
589         ge I0, I10, postCheckBuildUpLeft
590         set I2, P0[I0]
591         mul I3, I0, 3
592         mod I3, 2
593         ne I2, I3, errLeftGet
594         add I0, 1
595         branch checkBuildUpLeft
596 postCheckBuildUpLeft:
598         mul I0, I10, -1
599 checkBuildUpRight:
600         ge I0, 0, postCheckBuildUpRight
601         set I2, P0[I0]
602         add I3, I0, I10
603         mul I3, 3
604         mod I3, 2
605         ne I2, I3, errRightGet
606         add I0, 1
607         branch checkBuildUpRight
608 postCheckBuildUpRight:
610         set I0, I10
611 tearDown:
612         le I0, 0, postTearDown
613         pop I2, P0
614         sub I3, I0, 1
615         mod I3, 2
616         ne I2, I3, errTearDown
618         sub I0, 1
619         branch tearDown
620 postTearDown:
622         print "I need a shower.\n"
623         end
624 errFirstPop:
625         print "FAILED: first pop\n"
626         bsr info
627         end
628 errSecondPop:
629         print "FAILED: second pop\n"
630         bsr info
631         end
632 errBuildLen:
633         print "FAILED: buildup length\n"
634         bsr info
635         end
636 errLeftGet:
637         print "FAILED: left get\n"
638         bsr info
639         end
640 errRightGet:
641         print "FAILED: right get\n"
642         bsr info
643         end
644 errTearDown:
645         print "FAILED: tear down cap\n"
646         bsr info
647         end
648 info:
649         print "Found: "
650         print I2
651         print "\nWanted: "
652         print I3
653         print "\n"
654         ret
655 CODE
656 I need a shower.
657 OUTPUT
659 pasm_output_is( <<'CODE', <<'OUTPUT', "direct access 2" );
660     #new P0, .IntList
661     new P0, .ResizableBooleanArray
662     set I10, 550000
663     set I0, 1
664 lp1:
665     add I1, I0, 5
666     mod I2, I1, 2
667     set P0[I0], I2
668     add I3, I1, I0
669     mod I2, I3, 2
670     push P0, I2
671     shl I0, I0, 1
672     inc I0
673     le I0, I10, lp1
675     set I0, 1
676 lp2:
677     add I1, I0, 5
678     mod I5, I1, 2
679     # check at I0
680     set I2, P0[I0]
681     ne I2, I5, err
682     add I4, I0, 1
683     # and pushed value at I0+1
684     set I4, P0[I4]
685     add I3, I1, I0
686     mod I5, I3, 2
687     ne I5, I4, err
689     shl I0, I0, 1
690     inc I0
691     le I0, I10, lp2
692     print "ok\n"
693     end
694 err:
695     print "not ok "
696     print I0
697     print " "
698     print I1
699     print " "
700     print I2
701     print " "
702     print I3
703     print " "
704     print I4
705     print " "
706     print I5
707     print " "
708     print I6
709     print " "
710     print I7
711     print "\n"
713     end
714 CODE
716 OUTPUT
718 pasm_output_is( <<'CODE', <<'OUTPUT', "sparse access" );
719     new P0, .ResizableBooleanArray
720        set I10, 110000
721        set I0, 1
722 lp1:
723        add I1, I0, 5
724     mod I9, I1, 2
725        set P0[I0], I9
726        add I3, I1, I0
727     mod I9, I3, 2
728        push P0, I9
729        shl I0, I0, 1
730        inc I0
731        le I0, I10, lp1
733        set I0, 1
734 lp2:
735        add I1, I0, 5
736     mod I9, I1, 2
737        # check at I0
738        set I2, P0[I0]
739        ne I2, I9, err
740        add I4, I0, 1
741        # and pushed value at I0+1
742        set I4, P0[I4]
743        add I3, I1, I0
744     mod I9, I3, 2
745        ne I9, I4, err
747        shl I0, I0, 1
748        inc I0
749        le I0, I10, lp2
750        print "ok 1\n"
752        # now repeat and fill some holes
754        set I0, 777
755 lp3:
756        add I1, I0, 5
757     mod I9, I1, 2
758        set P0[I0], I9
759        add I0, I0, 666
760        le I0, I10, lp3
762        set I0, 777
763 lp4:
764        add I1, I0, 5
765     mod I9, I1, 2
766        # check at I0
767        set I2, P0[I0]
768        ne I2, I9, err
770        add I0, I0, 666
771        le I0, I10, lp4
772        print "ok 2\n"
773        end
774 err:
775        print "not ok "
776        print I0
777        print " "
778        print I1
779        print " "
780        print I2
781        print " "
782        print I3
783        print " "
784        print I4
785        print "\n"
787        end
788 CODE
789 ok 1
790 ok 2
791 OUTPUT
794 pasm_output_is( <<'CODE', <<'OUTPUT', "check for zeroedness" );
795     new P0, .ResizableBooleanArray
796     set I0, 0
797 lp1:
798     push P0, 0
799     inc I0
800     lt I0, 100, lp1
802     set I2, 10000
803     #set I0, 100
804     set P0, I2
805 lp2:
806     set I1, P0[I0]
807     ne I1, 0, err
808     inc I0
809     lt I0, I2, lp2
810     print "ok\n"
811     end
812 err:
813     print "Found non-zero value "
814     print I1
815     print " at "
816     print I0
817     print "\n"
818     end
819 CODE
821 OUTPUT
823 pasm_output_is( <<'CODE', <<'OUTPUT', "pop into sparse" );
824     new P0, .ResizableBooleanArray
825        set I10, 100
826        set I0, 0
827        # push some values at start
828 loop1:
829     mod I5, I0, 2
830        push P0, I5
831        inc I0
832        lt I0, I10, loop1
834        # create sparse
835        set I0, 100000
836        set I1, 1000
837     mod I5, I1, 2
838        #set P0[I0], I1
839        set P0[I0], I5
840        inc I1
841 loop2:
842        # push some values after hole
843     mod I5, I1, 2
844        push P0, I5
845        inc I1
846        le I1, 1100, loop2
847        dec I1
849        set I3, P0
850 lp3:
851        set I4, P0
852        ne I3, I4, err1
853        pop I2, P0
854        dec I3
855     mod I5, I1, 2
856        ne I2, I5, err2
857        gt I3, I0, cont1
858        lt I3, I10, cont1
859        set I1, 0
861        gt I3, I10, lp3
862        set I1, I10
864 cont1:
865        dec I1
866        eq I1, 0, ok
867        branch lp3
869        print "ok\n"
870        end
871 err1:   set S0, "len"
872        branch err
873 err2:
874        set S0, "val"
875 err:
876        print "nok "
877        print S0
878        print " "
879        print I0
880        print " "
881        print I1
882        print " "
883        print I2
884        print " "
885        print I3
886        print " "
887        print I4
888        print " "
889        print I5
890        end
891 CODE
893 OUTPUT
895 TODO: {
896     local $TODO = "this is broken";
898     pasm_output_is( <<'CODE', <<'OUTPUT', "clone" );
899     new P0, .ResizableBooleanArray
900        set P0[0], 1
901        set P0[5000], 1
902        clone P1, P0
904        set I0, P0[5000]
905        eq I0, 1, ok_1
906        print "nok 1 "
907 ok_1:
908        pop I0, P0
909        eq I0, 1, ok_2
910        print "nok 2 "
911 ok_2:
912        set I0, P0
913        eq I0, 5000, ok_3
914        print "nok 3 "
915 ok_3:
916        set I0, P1
917        eq I0, 5000, ok_4
918        print "nok 4 "
919 ok_4:
920        set I0, P1[5000]
921        eq I0, 1, ok_5
922        print "nok 5 "
923 ok_5:
924        pop I0, P1
925        eq I0, 1, ok_6
926        print "nok 6 "
927        end
928 ok_6:
929        print "ok\n"
930        end
931 CODE
933 OUTPUT
935 }    # TODO
937 # Local Variables:
938 #   mode: cperl
939 #   cperl-indent-level: 4
940 #   fill-column: 100
941 # End:
942 # vim: expandtab shiftwidth=4: