1#! perl
2# Copyright (C) 2001-2009, Parrot Foundation.
3
4use strict;
5use warnings;
6use lib qw( . lib ../lib ../../lib );
7use Test::More;
8use Parrot::Test tests => 38;
9use Parrot::Config;
10
11=head1 NAME
12
13t/pmc/namespace.t - test the NameSpace PMC as described in PDD 21.
14
15=head1 SYNOPSIS
16
17    % prove t/pmc/namespace-old.t
18
19=head1 DESCRIPTION
20
21Test the NameSpace PMC as described in PDD21.
22
23=cut
24
25my $temp_a = "temp_a";
26my $temp_b = "temp_b";
27
28END {
29    unlink( "$temp_a.pir", "$temp_a.pbc", "$temp_b.pir", "$temp_b.pbc" );
30}
31
32open my $S, '>', "$temp_a.pir" or die "Can't write $temp_a.pir";
33print $S <<'EOF';
34.HLL "Foo"
35.namespace ["Foo_A"]
36.sub loada :load
37    $P0 = get_global ["Foo_A"], "A"
38    print "ok 1\n"
39    load_bytecode "temp_b.pbc"
40.end
41
42.sub A
43.end
44EOF
45close $S;
46
47open $S, '>', "$temp_b.pir" or die "Can't write $temp_b.pir";
48print $S <<'EOF';
49.namespace ["Foo_B"]
50.sub loadb :load
51    $P0 = get_global ["Foo_B"], "B"
52    print "ok 2\n"
53.end
54
55.sub B
56.end
57EOF
58
59close $S;
60
61system(".$PConfig{slash}parrot$PConfig{exe} -o $temp_a.pbc $temp_a.pir");
62system(".$PConfig{slash}parrot$PConfig{exe} -o $temp_b.pbc $temp_b.pir");
63
64pir_output_is( <<'CODE', <<'OUTPUT', "HLL and load_bytecode - #38888" );
65.sub main :main
66    load_bytecode "temp_a.pbc"
67    print "ok 3\n"
68.end
69CODE
70ok 1
71ok 2
72ok 3
73OUTPUT
74
75pir_output_is( <<'CODE', <<'OUTPUT', "HLL and vars" );
76# initial storage of _tcl global variable...
77
78.HLL '_Tcl'
79
80.sub huh
81  $P0 = new ['Integer']
82  $P0 = 3.14
83  set_global '$variable', $P0
84.end
85
86# start running HLL language
87.HLL 'Tcl'
88
89.sub foo :main
90  huh()
91  $P1 = get_root_namespace ['_tcl']
92  $P2 = $P1['$variable']
93  print $P2
94  print "\n"
95.end
96CODE
973.14
98OUTPUT
99
100pir_output_is( <<'CODE', <<'OUTPUT', "HLL and namespace directives" );
101.HLL '_Tcl'
102.namespace ['Foo'; 'Bar']
103
104.HLL 'Tcl'
105
106.sub main :main
107  $P0 = get_namespace
108  $P1 = $P0.'get_name'()
109  $S0 = join "::", $P1
110  print $S0
111  print "\n"
112  end
113.end
114CODE
115tcl
116OUTPUT
117
118{
119    my $temp_a = "temp_a.pir";
120
121    END {
122        unlink($temp_a);
123    }
124
125    open $S, '>', $temp_a or die "Can't write $temp_a";
126    print $S <<'EOF';
127.HLL 'eek'
128
129.sub foo :load :anon
130  $P1 = new ['String']
131  $P1 = "3.14\n"
132  set_global '$whee', $P1
133.end
134
135.sub bark
136  $P0 = get_global '$whee'
137  print $P0
138.end
139EOF
140    close $S;
141
142    pir_output_is( <<'CODE', <<'OUTPUT', ":anon subs still get default namespace" );
143.HLL 'cromulent'
144
145.sub what :main
146   load_bytecode 'temp_a.pir'
147  .local pmc var
148   var = get_root_namespace
149   var = var['eek']
150   var = var['bark']
151
152    var()
153.end
154CODE
1553.14
156OUTPUT
157}
158
159SKIP:
160{
161    skip( "immediate test, doesn't with --run-pbc", 1 )
162        if ( exists $ENV{TEST_PROG_ARGS} and $ENV{TEST_PROG_ARGS} =~ m/--run-pbc/ );
163
164    pir_output_is( <<'CODE', <<'OUTPUT', "get_global in current" );
165.HLL 'bork'
166.namespace []
167
168.sub a :immediate
169  $P1 = new ['String']
170  $P1 = "ok\n"
171  set_global ['sub_namespace'], "eek", $P1
172.end
173
174.namespace [ 'sub_namespace' ]
175
176.sub whee :main
177 $P1 = get_global 'eek'
178 print $P1
179.end
180CODE
181ok
182OUTPUT
183}
184
185open $S, '>', "$temp_b.pir" or die "Can't write $temp_b.pir";
186print $S <<'EOF';
187.HLL 'B'
188.sub b_foo
189    print "b_foo\n"
190.end
191EOF
192close $S;
193
194pir_output_is( <<"CODE", <<'OUTPUT', "export_to -- success with array" );
195.HLL 'A'
196.sub main :main
197    a_foo()
198    load_bytecode "$temp_b.pir"
199    .local pmc nsr, nsa, nsb, ar
200    ar = new ['ResizableStringArray']
201    push ar, "b_foo"
202    nsr = get_root_namespace
203    nsa = nsr['a']
204    nsb = nsr['b']
205    nsb."export_to"(nsa, ar)
206    b_foo()
207.end
208
209.sub a_foo
210    print "a_foo\\n"
211.end
212CODE
213a_foo
214b_foo
215OUTPUT
216
217pir_output_is( <<"CODE", <<'OUTPUT', "export_to -- success with hash (empty value)" );
218.HLL 'A'
219.sub main :main
220    a_foo()
221    load_bytecode "$temp_b.pir"
222    .local pmc nsr, nsa, nsb, ar
223    ar = new ['Hash']
224    ar["b_foo"] = ""
225    nsr = get_root_namespace
226    nsa = nsr['a']
227    nsb = nsr['b']
228    nsb."export_to"(nsa, ar)
229    b_foo()
230.end
231
232.sub a_foo
233    print "a_foo\\n"
234.end
235CODE
236a_foo
237b_foo
238OUTPUT
239
240pir_output_is( <<"CODE", <<'OUTPUT', "export_to -- success with hash (null value)" );
241.HLL 'A'
242.sub main :main
243    a_foo()
244    load_bytecode "$temp_b.pir"
245    .local pmc nsr, nsa, nsb, ar, nul
246    nul = new ['Null']
247    ar  = new ['Hash']
248    ar["b_foo"] = nul
249    nsr = get_root_namespace
250    nsa = nsr['a']
251    nsb = nsr['b']
252    nsb."export_to"(nsa, ar)
253    b_foo()
254.end
255
256.sub a_foo
257    print "a_foo\\n"
258.end
259CODE
260a_foo
261b_foo
262OUTPUT
263
264pir_error_output_like( <<"CODE", <<'OUTPUT', "export_to -- success with hash (and value)" );
265.HLL 'A'
266.sub main :main
267    a_foo()
268    load_bytecode "$temp_b.pir"
269    .local pmc nsr, nsa, nsb, ar
270    ar = new ['Hash']
271    ar["b_foo"] = "c_foo"
272    nsr = get_root_namespace
273    nsa = nsr['a']
274    nsb = nsr['b']
275    nsb."export_to"(nsa, ar)
276    c_foo()
277    b_foo()
278.end
279
280.sub a_foo
281    print "a_foo\\n"
282.end
283CODE
284/^a_foo
285b_foo
286Could not find sub b_foo/
287OUTPUT
288
289
290pir_output_is( <<'CODE', <<'OUTPUT', "get_parent" );
291.sub main :main
292    .local pmc ns
293    ns = get_hll_namespace ['Foo']
294    ns = ns.'get_parent'()
295    print ns
296    print "\n"
297.end
298.namespace ['Foo']
299.sub dummy
300.end
301CODE
302parrot
303OUTPUT
304
305pir_output_is( <<'CODE', <<'OUTPUT', "get_global [''], \"print_ok\"" );
306.namespace ['']
307
308.sub print_ok
309  print "ok\n"
310  .return()
311.end
312
313.namespace ['foo']
314
315.sub main :main
316  $P0 = get_hll_global [''], 'print_ok'
317  $P0()
318  end
319.end
320CODE
321ok
322OUTPUT
323
324pir_output_is( <<'CODE', <<'OUTPUT', "get_global with array ('')" );
325.namespace ['']
326
327.sub print_ok
328  print "ok\n"
329  .return()
330.end
331
332.namespace ['foo']
333
334.sub main :main
335  $P0 = new ['ResizableStringArray']
336  $P0[0] = ''
337  $P0 = get_hll_global $P0, 'print_ok'
338  $P0()
339  end
340.end
341CODE
342ok
343OUTPUT
344
345pir_output_is( <<'CODE', <<'OUTPUT', "get_global with empty array" );
346.namespace []
347
348.sub print_ok
349  print "ok\n"
350  .return()
351.end
352
353.namespace ['foo']
354
355.sub main :main
356  $P0 = new ['ResizablePMCArray']
357  $P0 = 0
358  $P0 = get_hll_global $P0, 'print_ok'
359  $P0()
360  end
361.end
362CODE
363ok
364OUTPUT
365
366pir_output_is( <<'CODE', <<'OUTPUT', "Namespace.get_global() with array ('')" );
367.namespace ['']
368
369.sub print_ok
370  print "ok\n"
371  .return()
372.end
373
374.namespace ['foo']
375
376.sub main :main
377  $P1 = new ['ResizableStringArray']
378  $P1[0] = ''
379  $P1 = get_hll_global $P1, 'print_ok'
380  $P1()
381  end
382.end
383CODE
384ok
385OUTPUT
386
387pir_output_is( <<'CODE', <<'OUTPUT', "Namespace introspection" );
388.sub main :main
389    .local pmc f
390    f = get_hll_global ['Foo'], 'dummy'
391    f()
392.end
393.namespace ['Foo']
394.sub dummy
395    .local pmc interp, ns_caller
396    interp = getinterp
397    ns_caller = interp['namespace'; 1]
398    print ns_caller
399    print "\n"
400.end
401CODE
402parrot
403OUTPUT
404
405pir_output_is( <<'CODE', <<'OUTPUT', "Nested namespace introspection" );
406.sub main :main
407    .local string no_symbol
408
409    .local pmc foo_ns
410    foo_ns = get_hll_namespace [ 'Foo' ]
411    $S0    = foo_ns
412    print "Found namespace: "
413    print $S0
414    print "\n"
415
416    .local pmc bar_ns
417    bar_ns = foo_ns.'find_namespace'( 'Bar' )
418    $S0    = bar_ns
419    print "Found nested namespace: "
420    print $S0
421    print "\n"
422
423    .local pmc baz_ns
424    baz_ns    = bar_ns.'find_namespace'( 'Baz' )
425    no_symbol = 'Baz'
426
427    .local int is_defined
428    is_defined = defined baz_ns
429    if is_defined goto oops
430    goto find_symbols
431
432  oops:
433    print "Found non-null '"
434    print no_symbol
435    print "'\n"
436    .return()
437
438  find_symbols:
439    .local pmc a_sub
440    a_sub = bar_ns.'find_sub'( 'a_sub' )
441    $S0   = a_sub
442    a_sub()
443    print "Found sub: "
444    print $S0
445    print "\n"
446
447    .local pmc some_sub
448    some_sub  = bar_ns.'find_sub'( 'some_sub' )
449    no_symbol = 'some_sub'
450
451    is_defined = defined some_sub
452    if is_defined goto oops
453
454    .local pmc a_var
455    a_var    = bar_ns.'find_var'( 'a_var' )
456    print "Found var: "
457    print a_var
458    print "\n"
459
460    .local pmc some_var
461    some_var    = bar_ns.'find_var'( 'some_var' )
462    no_symbol = 'some_var'
463
464    is_defined = defined some_var
465    if is_defined goto oops
466
467.end
468
469.namespace ['Foo']
470
471.sub some_sub
472.end
473
474.namespace [ 'Foo'; 'Bar' ]
475
476.sub a_sub
477    .local pmc some_var
478    some_var = new ['String']
479    some_var = 'a string PMC'
480    set_hll_global [ 'Foo'; 'Bar' ], 'a_var', some_var
481.end
482CODE
483Found namespace: Foo
484Found nested namespace: Bar
485Found sub: a_sub
486Found var: a string PMC
487OUTPUT
488
489pir_output_is( <<'CODE', <<'OUTPUT', 'get_root_namespace' );
490.sub main :main
491    .local pmc root_ns
492    root_ns = get_root_namespace
493    .local int is_defined
494    is_defined = defined root_ns
495    unless is_defined goto NO_NAMESPACE_FOUND
496        print "Found root namespace.\n"
497    NO_NAMESPACE_FOUND:
498.end
499CODE
500Found root namespace.
501OUTPUT
502
503pir_output_is( <<'CODE', <<'OUTPUT', 'root namespace is not a class' );
504.sub main :main
505    .local pmc root_ns
506    root_ns = get_root_namespace
507    .local pmc root_class
508    root_class = get_class root_ns
509    .local int is_class
510    is_class = defined root_class
511    say is_class
512.end
513CODE
5140
515OUTPUT
516
517pir_output_is( <<'CODE', <<'OUTPUT', 'get_root_namespace "Foo"' );
518.sub main :main
519    .local pmc foo_ns
520    foo_ns = get_root_namespace [ "foo" ]
521    .local int is_defined
522    is_defined = defined foo_ns
523    unless is_defined goto NO_NAMESPACE_FOUND
524        print "Found root namespace 'foo'.\n"
525    NO_NAMESPACE_FOUND:
526.end
527.HLL 'Foo'
528.sub dummy
529.end
530CODE
531Found root namespace 'foo'.
532OUTPUT
533
534pir_output_is( <<'CODE', <<'OUTPUT', 'get_root_namespace "Foo", not there' );
535.sub main :main
536    .local pmc foo_ns
537    foo_ns = get_root_namespace [ "Foo" ]
538    .local int is_defined
539    is_defined = defined foo_ns
540    if is_defined goto NAMESPACE_FOUND
541        print "Didn't find root namespace 'Foo'.\n"
542    NAMESPACE_FOUND:
543.end
544
545.namespace [ "NotFoo" ]
546CODE
547Didn't find root namespace 'Foo'.
548OUTPUT
549
550my $create_nested_key = <<'CREATE_NESTED_KEY';
551.sub create_nested_key
552    .param string name
553    .param pmc other_names :slurpy
554
555    .local pmc key
556    key = new ['Key']
557    key = name
558
559    .local int elem
560    elem = other_names
561
562    if elem goto nested
563    .return( key )
564
565  nested:
566    .local pmc tail
567    tail = create_nested_key(other_names :flat)
568    push key, tail
569
570    .return( key )
571.end
572CREATE_NESTED_KEY
573
574pir_output_is( <<"CODE", <<'OUTPUT', 'get_name()' );
575$create_nested_key
576
577.sub main :main
578    .local pmc key
579    key = create_nested_key( 'SingleName' )
580    print_namespace( key )
581
582    key = create_nested_key( 'Nested', 'Name', 'Space' )
583    print_namespace( key )
584
585    key = get_namespace
586
587    .local pmc ns
588    ns = key.'get_name'()
589
590    .local string ns_name
591    ns_name = join ';', ns
592    print ns_name
593    print "\\n"
594.end
595
596.sub 'print_namespace'
597    .param pmc key
598
599    .local pmc get_ns
600    get_ns = get_global key, 'get_namespace'
601
602    .local pmc ns
603    ns = get_ns()
604
605    .local pmc name_array
606    name_array = ns.'get_name'()
607
608    .local string name
609    name = join ';', name_array
610
611    print name
612    print "\\n"
613.end
614
615.sub get_namespace
616    .local pmc ns
617    ns = get_namespace
618    .return( ns )
619.end
620
621.namespace [ 'SingleName' ]
622
623.sub get_namespace
624    .local pmc ns
625    ns = get_namespace
626    .return( ns )
627.end
628
629.namespace [ 'Nested'; 'Name'; 'Space' ]
630
631.sub get_namespace
632    .local pmc ns
633    ns = get_namespace
634    .return( ns )
635.end
636
637CODE
638parrot;SingleName
639parrot;Nested;Name;Space
640parrot
641OUTPUT
642
643pir_output_is( <<"CODE", <<'OUTPUT', 'add_namespace()' );
644$create_nested_key
645
646.sub main :main
647    .local pmc root_ns
648    root_ns = get_namespace
649
650    .local pmc child_ns
651    child_ns = new ['NameSpace']
652    root_ns.'add_namespace'( 'Nested', child_ns )
653
654    .local pmc grandchild_ns
655    grandchild_ns = new ['NameSpace']
656    child_ns.'add_namespace'( 'Grandkid', grandchild_ns )
657
658    .local pmc great_grandchild_ns
659    great_grandchild_ns = new ['NameSpace']
660    grandchild_ns.'add_namespace'( 'Greatgrandkid', great_grandchild_ns )
661
662    .local pmc parent
663    parent = great_grandchild_ns.'get_parent'()
664    print_ns_name( parent )
665
666    parent = parent.'get_parent'()
667    print_ns_name( parent )
668
669    parent = parent.'get_parent'()
670    print_ns_name( parent )
671.end
672
673.sub print_ns_name
674    .param pmc namespace
675
676    .local pmc ns
677    ns = namespace.'get_name'()
678
679    .local string ns_name
680    ns_name = join ';', ns
681    print ns_name
682    print "\\n"
683.end
684CODE
685parrot;Nested;Grandkid
686parrot;Nested
687parrot
688OUTPUT
689
690pir_output_like( <<'CODE', <<'OUTPUT', 'add_namespace() with error' );
691.sub main :main
692    .local pmc ns_child
693    ns_child = subclass 'NameSpace', 'NSChild'
694
695    .local pmc child
696    child = new ['NSChild']
697
698    .local pmc root_ns
699    root_ns = get_namespace
700
701    root_ns.'add_namespace'( 'Really nested', child )
702
703    .local pmc not_a_ns
704    not_a_ns = new ['Integer']
705
706    push_eh _invalid_ns
707    root_ns.'add_namespace'( 'Nested', not_a_ns )
708    end
709
710_invalid_ns:
711    .local pmc exception
712    .local string message
713    .get_results( exception )
714
715    message = exception
716    print message
717    print "\n"
718.end
719CODE
720/Invalid type \d+ in add_namespace\(\)/
721OUTPUT
722
723pir_output_is( <<"CODE", <<'OUTPUT', 'add_sub()' );
724$create_nested_key
725
726.sub 'main' :main
727    .local pmc report_ns
728    report_ns = get_global 'report_namespace'
729
730    .local pmc key
731    key = create_nested_key( 'Parent' )
732
733    .local pmc parent_ns
734    parent_ns = get_namespace key
735    parent_ns.'add_sub'( 'report_ns', report_ns )
736
737    key = create_nested_key( 'Parent', 'Child' )
738
739    .local pmc child_ns
740    child_ns = get_namespace key
741    child_ns.'add_sub'( 'report_ns', report_ns )
742
743    .local pmc report_namespace
744    report_namespace = get_global [ 'Parent' ], 'report_ns'
745    report_namespace()
746
747    report_namespace = get_global [ 'Parent'; 'Child' ], 'report_ns'
748    report_namespace()
749.end
750
751.sub 'report_namespace'
752    .local pmc namespace
753    namespace = get_namespace
754
755    .local pmc ns
756    ns = namespace.'get_name'()
757
758    .local string ns_name
759    ns_name = join ';', ns
760    print ns_name
761    print "\\n"
762.end
763
764.namespace [ 'Parent' ]
765
766.sub dummy
767.end
768
769.namespace [ 'Parent'; 'Child' ]
770
771.sub dummy
772.end
773CODE
774parrot
775parrot
776OUTPUT
777
778pir_output_like( <<'CODE', <<'OUTPUT', 'add_sub() with error' );
779.sub main :main
780    .local pmc s_child
781    s_child = subclass 'Sub', 'SubChild'
782
783    .local pmc child
784    child = new ['SubChild']
785
786    .local pmc root_ns
787    root_ns = get_namespace
788
789    root_ns.'add_sub'( 'child', child )
790    print "Added sub child\n"
791
792    child = new ['Coroutine']
793    root_ns.'add_sub'( 'coroutine', child )
794    print "Added coroutine\n"
795
796    .local pmc not_a_sub
797    not_a_sub = new ['Integer']
798
799    push_eh _invalid_sub
800    root_ns.'add_sub'( 'Nested', not_a_sub )
801    end
802
803_invalid_sub:
804    .local pmc exception
805    .local string message
806    .get_results( exception )
807
808    message = exception
809    print message
810    print "\n"
811.end
812CODE
813/Added sub child
814Added coroutine
815Invalid type \d+ in add_sub\(\)/
816OUTPUT
817
818pir_output_is( <<"CODE", <<'OUTPUT', 'add_var()' );
819$create_nested_key
820
821.sub 'main' :main
822    .local pmc foo
823    foo = new ['String']
824    foo = 'Foo'
825
826    .local pmc bar
827    bar = new ['String']
828    bar = 'Bar'
829
830    .local pmc key
831    key = create_nested_key( 'Parent' )
832
833    .local pmc parent_ns
834    parent_ns = get_namespace key
835    parent_ns.'add_var'( 'foo', foo )
836
837    key = create_nested_key( 'Parent', 'Child' )
838
839    .local pmc child_ns
840    child_ns = get_namespace key
841    child_ns.'add_var'( 'bar', bar )
842
843    .local pmc my_var
844    my_var = get_global [ 'Parent' ], 'foo'
845    print "Foo: "
846    print my_var
847    print "\\n"
848
849    my_var = get_global [ 'Parent'; 'Child' ], 'bar'
850    print "Bar: "
851    print my_var
852    print "\\n"
853.end
854
855.namespace [ 'Parent' ]
856
857.sub dummy
858.end
859
860.namespace [ 'Parent'; 'Child' ]
861
862.sub dummy
863.end
864CODE
865Foo: Foo
866Bar: Bar
867OUTPUT
868
869pir_output_is( <<"CODE", <<'OUTPUT', 'del_namespace()' );
870$create_nested_key
871
872.sub 'main' :main
873    .local pmc root_ns
874    root_ns = get_namespace
875
876    .local pmc key
877    key      = create_nested_key( 'Parent' )
878
879    .local pmc child_ns
880    child_ns = root_ns.'find_namespace'( key )
881
882    key      = create_nested_key( 'Child' )
883
884    .local pmc grandchild_ns
885    grandchild_ns = child_ns.'find_namespace'( key )
886
887    child_ns.'del_namespace'( 'Child' )
888
889    key      = create_nested_key( 'Child' )
890
891    grandchild_ns = child_ns.'find_namespace'( key )
892    if_null grandchild_ns, CHECK_SIBLING
893    print "Grandchild still exists\\n"
894
895  CHECK_SIBLING:
896    key      = create_nested_key( 'Sibling' )
897    grandchild_ns = child_ns.'find_namespace'( key )
898    if_null grandchild_ns, DELETE_PARENT
899    print "Sibling not deleted\\n"
900
901  DELETE_PARENT:
902    key      = create_nested_key( 'Parent' )
903    root_ns.'del_namespace'( 'Parent' )
904    child_ns = root_ns.'find_namespace'( key )
905    if_null child_ns, CHECK_UNCLE
906    print "Child still exists\\n"
907
908  CHECK_UNCLE:
909    key      = create_nested_key( 'FunUncle' )
910    grandchild_ns = root_ns.'find_namespace'( key )
911    if_null grandchild_ns, DELETE_PARENT
912    print "Fun uncle stuck around\\n"
913
914  ALL_DONE:
915.end
916
917.namespace [ 'FunUncle' ]
918
919.sub dummy
920.end
921
922.namespace [ 'Parent' ]
923
924.sub dummy
925.end
926
927.namespace [ 'Parent'; 'Child' ]
928
929.sub dummy
930.end
931
932.namespace [ 'Parent'; 'Sibling' ]
933
934.sub dummy
935.end
936CODE
937Sibling not deleted
938Fun uncle stuck around
939OUTPUT
940
941pir_output_like( <<'CODE', <<'OUTPUT', 'del_namespace() with error' );
942.sub dummy
943.end
944
945.sub main :main
946    .local pmc not_a_ns
947    not_a_ns = new ['ResizablePMCArray']
948
949    set_global 'Not_A_NS', not_a_ns
950
951    .local pmc root_ns
952    root_ns = get_namespace
953    delete_namespace( root_ns, 'dummy' )
954    delete_namespace( root_ns, 'Not_A_NS' )
955.end
956
957.sub delete_namespace
958    .param pmc    root_ns
959    .param string name
960    push_eh _invalid_ns
961    root_ns.'del_namespace'( name )
962
963_invalid_ns:
964    .local pmc exception
965    .local string message
966    .get_results( exception )
967
968    message = exception
969    print message
970    print "\n"
971    .return()
972.end
973CODE
974/Invalid type \d+ for 'dummy' in del_namespace\(\)
975Invalid type \d+ for 'Not_A_NS' in del_namespace\(\)/
976OUTPUT
977
978pir_output_is( <<"CODE", <<'OUTPUT', 'del_sub()' );
979.sub 'main' :main
980    .local pmc root_ns
981    root_ns = get_namespace
982
983    .local pmc parent_ns
984    parent_ns = root_ns.'find_namespace'( 'Parent' )
985    parent_ns.'del_sub'( 'dummy' )
986
987    .local pmc my_sub
988    my_sub = get_global [ 'Parent' ], 'dummy'
989    if_null my_sub, PARENT_NO_DUMMY
990    print "Parent did not delete dummy\\n"
991
992  PARENT_NO_DUMMY:
993    my_sub = get_global [ 'Parent' ], 'no_dummy'
994    my_sub()
995
996    .local pmc child_ns
997    child_ns = parent_ns.'find_namespace'( 'Child' )
998    child_ns.'del_sub'( 'dummy' )
999
1000    my_sub = get_global [ 'Parent'; 'Child' ], 'dummy'
1001    if_null my_sub, CHILD_NO_DUMMY
1002    print "Child did not delete dummy\\n"
1003    my_sub()
1004
1005  CHILD_NO_DUMMY:
1006    my_sub = get_global [ 'Parent'; 'Child' ], 'no_dummy'
1007    my_sub()
1008.end
1009
1010.namespace [ 'Parent' ]
1011
1012.sub dummy
1013.end
1014
1015.sub no_dummy
1016    print "Parent is no dummy\\n"
1017.end
1018
1019.namespace [ 'Parent'; 'Child' ]
1020
1021.sub dummy
1022    print "Dummy sub!\\n"
1023.end
1024
1025.sub no_dummy
1026    print "Child is no dummy\\n"
1027.end
1028
1029CODE
1030Parent is no dummy
1031Child is no dummy
1032OUTPUT
1033
1034pir_output_like( <<'CODE', <<'OUTPUT', 'del_sub() with error' );
1035.sub main :main
1036    .local pmc not_a_ns
1037    not_a_ns = new ['ResizablePMCArray']
1038
1039    set_global 'Not_A_Sub', not_a_ns
1040
1041    .local pmc root_ns
1042    root_ns = get_namespace
1043
1044    push_eh _invalid_sub
1045    root_ns.'del_sub'( 'Not_A_Sub' )
1046
1047_invalid_sub:
1048    .local pmc exception
1049    .local string message
1050    .get_results( exception )
1051
1052    message = exception
1053    print message
1054    print "\n"
1055    .return()
1056.end
1057CODE
1058/Invalid type \d+ for 'Not_A_Sub' in del_sub\(\)/
1059OUTPUT
1060
1061pir_output_is( <<"CODE", <<'OUTPUT', 'del_var()' );
1062.sub 'main' :main
1063    .local pmc foo
1064    foo = new ['String']
1065    foo = 'Foo'
1066
1067    .local pmc bar
1068    bar = new ['String']
1069    bar = 'Bar'
1070
1071    set_global [ 'Parent' ],          'Foo', foo
1072    set_global [ 'Parent'; 'Child' ], 'Bar', bar
1073
1074    .local pmc root_ns
1075    root_ns = get_namespace
1076
1077    .local pmc parent_ns
1078    parent_ns = root_ns.'find_namespace'( 'Parent' )
1079    parent_ns.'del_var'( 'Foo' )
1080
1081    .local pmc child_ns
1082    child_ns = parent_ns.'find_namespace'( 'Child' )
1083    child_ns.'del_var'( 'Bar' )
1084
1085    .local pmc my_var
1086    my_var = get_global [ 'Parent' ], 'Foo'
1087    if_null my_var, TEST_CHILD_VAR
1088    print "Parent Foo exists: "
1089    print my_var
1090    print "\\n"
1091
1092  TEST_CHILD_VAR:
1093    my_var = get_global [ 'Parent'; 'Child' ], 'Bar'
1094    if_null my_var, ALL_DONE
1095    print "Child Bar exists: "
1096    print my_var
1097    print "\\n"
1098
1099  ALL_DONE:
1100.end
1101
1102.namespace [ 'Parent' ]
1103
1104.sub dummy
1105.end
1106
1107.namespace [ 'Parent'; 'Child' ]
1108
1109CODE
1110OUTPUT
1111
1112pir_error_output_like( <<'CODE', <<'OUTPUT', 'overriding find_method()' );
1113.sub 'main' :main
1114    $P0 = newclass 'Override'
1115    $P1 = new ['Override']
1116    $P2 = find_method $P1, 'foo'
1117.end
1118
1119.namespace [ 'Override' ]
1120
1121.sub 'find_method' :vtable
1122    .param string method
1123    say "Finding method"
1124.end
1125CODE
1126/Finding method/
1127OUTPUT
1128
1129pir_output_is( <<'CODE', <<OUT, "iterate through a NameSpace PMC" );
1130.sub main :main
1131     $P0 = new ['String']
1132     $P0 = "Ook...BANG!\n"
1133     set_root_global [ "DUMMY"; "X"; "Y" ], "Explosion", $P0
1134
1135     $P1 = new ['Integer']
1136     $P1 = 0
1137     set_root_global [ "DUMMY"; "X"; "Y" ], "T0", $P0
1138
1139     .local pmc dummy_x_y_ns, it, res
1140     dummy_x_y_ns = get_root_namespace [ "DUMMY"; "X"; "Y" ]
1141     it   = iter dummy_x_y_ns
1142     res  = new ['ResizablePMCArray']
1143loop:
1144     unless it goto loop_end
1145     $S0 = shift it
1146     push res, $S0
1147     goto loop
1148loop_end:
1149
1150     res.'sort'()
1151     $S0 = join ' ', res
1152     say $S0
1153
1154.end
1155CODE
1156Explosion T0
1157OUT
1158
1159pir_error_output_like( <<'CODE', <<OUT, "NameSpace with no class" );
1160.sub 'main' :main
1161    $P1 = new ['NameSpace']
1162    set_args '(0)', $P1
1163    tailcallmethod $P1, 'bob'
1164.end
1165CODE
1166/Null PMC access in get_string()/
1167OUT
1168
1169pir_output_is( <<'CODE', <<OUT, "iterate through a NameSpace PMC" );
1170.namespace [ 'bar' ]
1171
1172.sub 'main' :main
1173    .local pmc res
1174    res = new ['ResizablePMCArray']
1175
1176    $P0 = get_namespace
1177    say $P0
1178    $I0 = elements $P0
1179    say $I0
1180    $P1 = iter $P0
1181  L1:
1182    unless $P1 goto L2
1183    $P2 = shift $P1
1184    $S0 = $P2
1185    push res, $S0
1186    goto L1
1187  L2:
1188    res.'sort'()
1189    $S0 = join "\n", res
1190    say $S0
1191    say 'OK'
1192.end
1193
1194.sub 'foo'
1195    say 'foo'
1196.end
1197CODE
1198bar
11992
1200foo
1201main
1202OK
1203OUT
1204
1205pir_output_is( <<'CODE', <<'OUT', "make_namespace method");
1206.sub 'main' :main
1207    $P0 = split ';', 'perl6;Foo;Bar'
1208    $P1 = get_root_namespace
1209    $P2 = $P1.'make_namespace'($P0)
1210    $I0 = isa $P2, 'NameSpace'
1211    say $I0
1212    $P3 = get_root_namespace ['perl6';'Foo';'Bar']
1213    $I0 = isnull $P3
1214    say $I0
1215    $I0 = issame $P2, $P3
1216    say $I0
1217.end
1218CODE
12191
12200
12211
1222OUT
1223
1224pir_error_output_like( <<'CODE', <<'OUT', 'adding :anon sub to a namespace, TT #56' );
1225.namespace ['Foo']
1226.sub main :main
1227    .const 'Sub' $P0 = 'bar'
1228
1229    set_global 'ok', $P0
1230    $P1 = get_global 'ok'
1231    say $P1
1232    $S0 = ok()
1233    say $S0
1234    $S0 = nok()
1235    say $S0
1236.end
1237
1238.namespace []
1239.sub 'nok' :anon :subid('bar')
1240    .return( 'ok 1' )
1241.end
1242CODE
1243/
1244ok 1
1245Could not find sub nok/
1246OUT
1247
1248
1249pir_output_is( <<'CODE', <<'OUT', 'HLL_map on namespace', todo => 'GH #404');
1250.HLL 'tcl'
1251
1252.sub 'foo' :anon :init
1253  $P1 = get_class 'NameSpace'
1254  $P2 = subclass $P1, 'BSNS'
1255  $P0 = getinterp
1256  $P0.'hll_map'($P1, $P2)
1257.end
1258
1259.namespace ['a';'b';'c']
1260
1261.sub 'hi'
1262  noop
1263.end
1264
1265.namespace []
1266
1267.sub 'blah' :main
1268  $P1 = get_hll_namespace ['a';'b';'c']
1269  $S0 = typeof $P1
1270  print 'ok 1 - '
1271  say $S0
1272.end
1273CODE
1274ok 1 - BSNS
1275OUT
1276
1277# Local Variables:
1278#   mode: cperl
1279#   cperl-indent-level: 4
1280#   fill-column: 100
1281# End:
1282# vim: expandtab shiftwidth=4:
1283