develooper Front page | perl.cvs.parrot | Postings from January 2009

[svn:parrot] r35817 - trunk/languages/perl6/src/parser

From:
jonathan
Date:
January 20, 2009 08:43
Subject:
[svn:parrot] r35817 - trunk/languages/perl6/src/parser
Message ID:
20090120164343.5F3FCCB9AE@x12.develooper.com
Author: jonathan
Date: Tue Jan 20 08:43:42 2009
New Revision: 35817

Modified:
   trunk/languages/perl6/src/parser/actions.pm

Log:
[rakudo] If a routine is marked as proto, then all routines after that not declared multi will be made to be multis.

Modified: trunk/languages/perl6/src/parser/actions.pm
==============================================================================
--- trunk/languages/perl6/src/parser/actions.pm	(original)
+++ trunk/languages/perl6/src/parser/actions.pm	Tue Jan 20 08:43:42 2009
@@ -556,20 +556,17 @@
         # If we're declaring a multi or a proto, flag the sub as :multi,
         # and transform the sub's container to a Perl6MultiSub.
         if $sym eq 'multi' || $sym eq 'proto' {
-            my $pirflags := ~$past.pirflags();
-            $past.pirflags( $pirflags ~ ' :multi()' );
-            $past.loadinit().push(
-                PAST::Op.new( :name('!TOPERL6MULTISUB'), :pasttype('call'),
-                    PAST::Var.new( :name('block'), :scope('register') )
-                )
-            );
+            transform_to_multi($past);
         }
 
-        # Protos also need the proto property setting on them.
+        # Protos also need the proto property setting on them, plus we note
+        # that we have one in scope.
         if $<sym> eq 'proto' {
             $past.loadinit().push(
                 PAST::Op.new(:inline('    setprop block, "proto", %0'), 1)
             );
+            our @?BLOCK;
+            @?BLOCK[0].symbol($past.name(), :does_callable(1), :is_proto(1));
         }
 
         # If it's just a routine, need to mark it as a sub and make sure we
@@ -906,6 +903,14 @@
     $past[0].push(
         PAST::Op.new( :pasttype('call'), :name('!SIGNATURE_BIND') )
     );
+    ##  If we have a proto in scope of this name, then we need to make this a
+    ##  multi.
+    if $past.name() ne "" {
+        my $sym := outer_symbol($past.name());
+        if $sym && $sym<does_callable> && $sym<is_proto> {
+            transform_to_multi($past);
+        }
+    }
     make $past;
 }
 
@@ -2858,6 +2863,21 @@
     }
 }
 
+
+# Makes a routine into a multi, if it isn't already one.
+sub transform_to_multi($past) {
+    unless $past<multi_flag> {
+        my $pirflags := ~$past.pirflags();
+        $past.pirflags( $pirflags ~ ' :multi()' );
+        $past.loadinit().push(
+            PAST::Op.new( :name('!TOPERL6MULTISUB'), :pasttype('call'),
+                PAST::Var.new( :name('block'), :scope('register') )
+            )
+        );
+        $past<multi_flag> := 1;
+    }
+}
+
 # Local Variables:
 #   mode: cperl
 #   cperl-indent-level: 4



nntp.perl.org: Perl Programming lists via nntp and http.
Comments to Ask Bjørn Hansen at ask@perl.org | Group listing | About