Author: pmichaud
Date: Thu Jan  1 23:00:12 2009
New Revision: 34792

Modified:
   branches/rvar/languages/perl6/src/builtins/guts.pir
   branches/rvar/languages/perl6/src/parser/actions.pm

Log:
[rakudo]:  Handle "is also" trait.


Modified: branches/rvar/languages/perl6/src/builtins/guts.pir
==============================================================================
--- branches/rvar/languages/perl6/src/builtins/guts.pir (original)
+++ branches/rvar/languages/perl6/src/builtins/guts.pir Thu Jan  1 23:00:12 2009
@@ -366,7 +366,7 @@
 .end
 
 
-=item !meta_create(type, name)
+=item !meta_create(type, name, also)
 
 Create a metaclass object for C<type> with the given C<name>.  
 This simply creates a handle on which we can hang methods, attributes,
@@ -378,10 +378,15 @@
 .sub '!meta_create'
     .param string type
     .param string name
+    .param int also
 
     .local pmc metaclass
+    if also goto is_also
     metaclass = newclass name
     .return (metaclass)
+  is_also:
+    metaclass = get_class name
+    .return (metaclass)
 .end 
 
 

Modified: branches/rvar/languages/perl6/src/parser/actions.pm
==============================================================================
--- branches/rvar/languages/perl6/src/parser/actions.pm (original)
+++ branches/rvar/languages/perl6/src/parser/actions.pm Thu Jan  1 23:00:12 2009
@@ -1342,36 +1342,35 @@
         $/.panic("Unable to parse " ~ $?PKGDECL ~ " definition");
     }
 
-    my $past := $( $/{$key} );
-    $past.blocktype('declaration');
+    my $block := $( $/{$key} );
+    $block.blocktype('declaration');
+    $block.lexical(0);
 
     my $modulename := $<module_name> 
                          ?? ~$<module_name>[0] !! 
-                         $past.unique('!ANON');
+                         $block.unique('!ANON');
     if ($modulename) {
-        $past.namespace( PAST::Compiler.parse_name( $modulename ) );
+        $block.namespace( PAST::Compiler.parse_name( $modulename ) );
     }
 
     if $key eq 'block' {
         # A normal block acts like a BEGIN and is executed ASAP.
-        $past.pirflags(':load :init');
+        $block.pirflags(':load :init');
     }
     elsif $key eq 'statement_block' && !$<module_name> {
         $/.panic("Compilation unit cannot be anonymous");
     }
+
     #  Create a node at the beginning of the block's initializer
     #  for package initializations
     my $init := PAST::Stmts.new();
-    $past[0].unshift( $init );
+    $block[0].unshift( $init );
 
-    #  At the beginning, create the "class/module/grammar/role/etc" 
-    #  metaclass handle on which we do the other operations.
-    $init.unshift( 
-        PAST::Op.new( :pasttype('bind'),
-            PAST::Var.new( :name('metaclass'), :scope('register'), :isdecl(1) 
),
-            PAST::Op.new( :name('!meta_create'), $?PKGDECL, $modulename )
-        )
-    );
+    #  Normally we would create the metaclass object first,
+    #  but if there's an "is also" trait we want to do a class
+    #  lookup instead.  So we do the trait processing first
+    #  (scanning for 'is also' as we go), and then decide how
+    #  to obtain the metaclass.
 
     #  Add any traits coming from the package declarator.
     #  Traits in the body have already been added to the block.
@@ -1382,17 +1381,31 @@
             #  We just modify them to call !meta_trait and add
             #  the metaclass as the first argument.
             my $trait := $( $_ );
-            $trait.name('!meta_trait');
-            $trait.unshift($metaclass);
-            $init.push($trait);
+            if $trait[1] eq 'also' { $block<isalso> := 1; }
+            else {
+                $trait.name('!meta_trait');
+                $trait.unshift($metaclass);
+                $init.push($trait);
+            }
         }
     }
 
-    #  ...and at the end of the block's initializer, we finalize any
-    #  composition that occurred.
-    $past[0].push( PAST::Op.new( :name('!meta_compose'), $metaclass) );
+    #  At the beginning, create the "class/module/grammar/role/etc" 
+    #  metaclass handle on which we do the other operations.
+    $init.unshift( 
+        PAST::Op.new( :pasttype('bind'),
+            PAST::Var.new(:name('metaclass'), :scope('register'), :isdecl(1) ),
+            PAST::Op.new(:name('!meta_create'), 
+                $?PKGDECL, $modulename, +$block<isalso>
+            )
+        )
+    );
 
-    make $past;
+    #  ...and at the end of the block's initializer (after any other
+    #  items added by the block), we finalize the composition
+    $block[0].push( PAST::Op.new( :name('!meta_compose'), $metaclass) );
+
+    make $block;
 }
 
 

Reply via email to