# 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> ]*
{*}