# New Ticket Created by  Jeff Horwitz 
# Please include the string:  [perl #56700]
# in the subject line of all future correspondence about this issue. 
# <URL: http://rt.perl.org/rt3/Ticket/Display.html?id=56700 >


I wanted some feedback on this patch before I apply it.  It implements 
"just enough" interpolated namespace support for mod_perl6 to work (see 
S02).  In fact, the only supported form is the following subroutine call:

   ::($ns)::foo()

It can most certainly be refactored to work with more test cases by someone 
with more PCT-fu than I currently have.  In the meantime, I'd like to 
apply this to avoid having to rewrite it every time there's a change in 
Rakudo, which is, um, often.  Please let me know if there are any 
glaring problems or a better way to implement it.  And yes, all tests 
still pass as of r29098.  :)

-jeff
Index: languages/perl6/src/builtins/misc.pir
===================================================================
--- languages/perl6/src/builtins/misc.pir       (revision 29098)
+++ languages/perl6/src/builtins/misc.pir       (working copy)
@@ -12,6 +12,19 @@
     .return($P0)
 .end
 
+.sub 'resolve_sym'
+    .param string ns
+    .param string name
+    .param pmc args :slurpy
+    .local pmc sym
+    .local pmc nskey
+
+    nskey = split '::', ns
+    sym = get_hll_global nskey, name
+
+    .return(sym)
+.end
+
 # Local Variables:
 #   mode: pir
 #   fill-column: 100
Index: languages/perl6/src/parser/actions.pm
===================================================================
--- languages/perl6/src/parser/actions.pm       (revision 29098)
+++ languages/perl6/src/parser/actions.pm       (working copy)
@@ -1930,6 +1930,27 @@
         $past := build_call( $( $<semilist> ) );
         $past.name( ~$<ident> );
     }
+    # call sub with an interpolated namespace
+    # right now we only support this exact form: ::($ns)::name()
+    elsif $key eq 'interpolated func args' {
+        my $resolve_past := PAST::Op.new(
+            :name('resolve_sym'),
+            :pasttype('call'),
+            :node($/)
+        );
+        $resolve_past.unshift(PAST::Val.new(
+            :value( ~$<interpolated_name><name><ident>[0] )
+        ));
+        $resolve_past.unshift(
+            $( $<interpolated_name><interpolated_ident>[0]<EXPR> )
+        );
+        $past := build_call( $( $<semilist> ) );
+        $past.unshift($resolve_past);
+
+        # build_call will set 'name' for us.  we reset that to undef so the
+        # sub call invokes the first PAST argument ($resolve_past) instead
+        $past.name(undef);
+    }
     elsif $key eq 'listop args' {
         $past := build_call( $( $<arglist> ) );
         $past.name( ~$<ident> );
Index: languages/perl6/src/parser/grammar.pg
===================================================================
--- languages/perl6/src/parser/grammar.pg       (revision 29098)
+++ languages/perl6/src/parser/grammar.pg       (working copy)
@@ -517,6 +517,8 @@
     [
     | 'VAR(' <variable> ')' {*}                  #= VAR
     | <typename> {*}                             #= typename
+    | <interpolated_name> <.unsp>? '.'?
+      '(' <semilist> ')' {*}                     #= interpolated func args
     | <ident=named_0ary>
         [
         | <.unsp>? '.'? '(' <semilist> ')' {*}   #= func args
@@ -604,10 +606,10 @@
 }
 
 token circumfix {
-    | '(' <statementlist> ')' {*}                #= ( )
-    | '[' <statementlist> ']' {*}                #= [ ]
-    | <?before '{' | <lambda> > <pblock> {*}     #= { }
-    | <sigil> '(' <semilist> ')' {*}             #= $( )
+    | '(' <statementlist> ')' {*}                   #= ( )
+    | '[' <statementlist> ']' {*}                   #= [ ]
+    | <?before '{' | <lambda> > <pblock> {*}        #= { }
+    | <sigil=variable_sigil> '(' <semilist> ')' {*} #= $( )
 }
 
 token variable {
@@ -619,6 +621,8 @@
 
 token sigil { '$' | '@' | '%' | '&' | '::' }
 
+token variable_sigil { '$' | '@' | '%' }
+
 token twigil { <[.!^:*+?=]> }
 
 token name {
@@ -718,6 +722,14 @@
     {*}
 }
 
+token interpolated_name {
+    [ '::' <interpolated_ident> ]+ '::' <name>
+}
+
+token interpolated_ident {
+    <?after '::' > '(' <EXPR> ')'
+}
+
 token name {
     <ident> [ '::' <ident> ]*
     {*}

Reply via email to