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;
 }

Reply via email to