Author: jonathan
Date: Thu Aug 7 13:36:44 2008
New Revision: 30104
Modified:
trunk/languages/perl6/src/parser/actions.pm
Log:
[rakudo] Make an empty block, a block containing just a pair or a block
containing a list that starts with a pair or a hash construct a Hash, as per
S06. Resolves RT##57340.
Modified: trunk/languages/perl6/src/parser/actions.pm
==============================================================================
--- trunk/languages/perl6/src/parser/actions.pm (original)
+++ trunk/languages/perl6/src/parser/actions.pm Thu Aug 7 13:36:44 2008
@@ -388,6 +388,7 @@
method statement_prefix($/) {
my $past := $($<statement>);
my $sym := ~$<sym>;
+
if $sym eq 'do' {
# fall through, just use the statement itself
}
@@ -2261,8 +2262,49 @@
if $<statementlist><statement> { $past.push( $( $<statementlist> ) ); }
}
elsif $key eq '{ }' {
+ # If it is completely empty or consists of a single list, the first
+ # element of which is either a hash or a pair, it's a hash constructor.
$past := $( $<pblock> );
- declare_implicit_function_vars($past);
+ my $is_hash := 0;
+ if +@($past) == 2 && +@($past[0]) == 0 {
+ if +@($past[1]) == 0 {
+ # Empty block, so a hash.
+ $is_hash := 1;
+ }
+ elsif +@($past[1]) == 1 && $past[1][0].WHAT() eq 'Op' {
+ if $past[1][0].name() eq 'infix:=>' {
+ # Block with just one pair in it, so a hash.
+ $is_hash := 1;
+ }
+ elsif $past[1][0].name() eq 'infix:,' {
+ # List, but first elements must be...
+ if $past[1][0][0].WHAT() eq 'Op' &&
+ $past[1][0][0].name() eq 'infix:=>' {
+ # ...a Pair
+ $is_hash := 1;
+ }
+ elsif $past[1][0][0].WHAT() eq 'Var' &&
+ substr($past[1][0][0].name(), 0, 1) eq '%' {
+ # ...or a hash.
+ $is_hash := 1
+ }
+ }
+ }
+ }
+ if $is_hash {
+ my @children := @($past[1]);
+ $past := PAST::Op.new(
+ :pasttype('call'),
+ :name('hash'),
+ :node($/)
+ );
+ for @children {
+ $past.push($_);
+ }
+ }
+ else {
+ declare_implicit_function_vars($past);
+ }
}
elsif $key eq '$( )' {
my $method := contextualizer_name($/, $<sigil>);
@@ -2404,7 +2446,9 @@
}
elsif ($key eq 'circumfix') {
$past := $( $<circumfix> );
- $past.blocktype('immediate');
+ if $past.WHAT() eq 'Block' {
+ $past.blocktype('immediate');
+ }
}
make $past;
}