Author: pmichaud
Date: Thu Jan  1 10:37:19 2009
New Revision: 34754

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

Log:
[rakudo]:  Refactor of basic class creation and inheritance.


Modified: branches/rvar/languages/perl6/perl6.pir
==============================================================================
--- branches/rvar/languages/perl6/perl6.pir     (original)
+++ branches/rvar/languages/perl6/perl6.pir     Thu Jan  1 10:37:19 2009
@@ -88,7 +88,7 @@
     setattribute perl6, '$version', $P0
 
     ##  create a list for holding the stack of nested blocks
-    $P0 = new 'List'
+    $P0 = new ['List']
     set_hll_global ['Perl6';'Grammar';'Actions'], '@?BLOCK', $P0
 
     ## create a list for holding the stack of nested packages
@@ -96,23 +96,10 @@
     $P0 = new 'List'
     set_hll_global ['Perl6';'Grammar';'Actions'], '@?PACKAGE', $P0
 
-    ## create a list for holding the stack of nested modules
-    ## (that may be roles, classes or grammars).
-    $P0 = new 'List'
-    set_hll_global ['Perl6';'Grammar';'Actions'], '@?MODULE', $P0
-
-    ## create a list for holding the stack of nested classes
-    ## (that may be classes or grammars).
-    $P0 = new 'List'
-    set_hll_global ['Perl6';'Grammar';'Actions'], '@?CLASS', $P0
-
-    ## create a list for holding the stack of nested roles
-    $P0 = new 'List'
-    set_hll_global ['Perl6';'Grammar';'Actions'], '@?ROLE', $P0
-
-    ## create a list for holding the stack of nested grammars
+    ## create a list for holding the stack of nested package
+    ## declarators
     $P0 = new 'List'
-    set_hll_global ['Perl6';'Grammar';'Actions'], '@?GRAMMAR', $P0
+    set_hll_global ['Perl6';'Grammar';'Actions'], '@?PKGDECL', $P0
 
     ##  create a list of END blocks to be run
     $P0 = new 'List'

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 10:37:19 2009
@@ -366,6 +366,63 @@
 .end
 
 
+=item !class_create(type, name)
+
+Create a metaclass object for C<type> with the given C<name>.  
+This simply creates a handle on which we can hang methods, attributes,
+traits, etc. -- the class itself isn't created until the class
+is composed (see C<!class_compose> below).
+
+=cut
+
+.sub '!class_create'
+    .param string type
+    .param string name
+
+    .local pmc metaclass
+    metaclass = newclass name
+    .return (metaclass)
+.end 
+
+
+=item !class_compose(Class metaclass)
+
+Compose the class.  This includes resolving any inconsistencies
+and creating the protoobjects.
+
+=cut
+
+.sub '!class_compose' :multi(['Class'])
+    .param pmc metaclass
+    .local pmc p6meta
+    p6meta = get_hll_global ['Perl6Object'], '$!P6META'
+
+    p6meta.'register'(metaclass, 'parent'=>'Any')
+.end
+
+
+=item !class_trait(metaclass, type, name)
+
+Add a trait with the given C<type> and C<name> to C<metaclass>.
+
+=cut
+
+.sub '!class_trait'
+    .param pmc metaclass
+    .param string type
+    .param string name
+
+    ##  get the (parrot)class object associated with name
+    $P0 = compreg 'Perl6'
+    $P0 = $P0.'parse_name'(name)
+    $P0 = get_hll_namespace $P0
+    $P0 = get_class $P0
+
+    ##  add it as parent to metaclass
+    metaclass.'add_parent'($P0)
+.end
+
+
 =item !keyword_class(name)
 
 Internal helper method to create a class.

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 10:37:19 2009
@@ -1345,11 +1345,72 @@
 
 method package_declarator($/, $key) {
     our @?PKGDECL;
-    my $sym := $<sym>;
-
+    my $sym := ~$<sym>;
+    my $past;
     if $key eq 'open' {
-        @?PKGDECL.push( $sym );
+        @?PKGDECL.unshift( $sym );
+    }
+    else {
+        make $( $<package_def> );
+        @?PKGDECL.shift();
+    }
+}
+
+
+method package_def($/, $key) {
+    our @?PKGDECL;
+    my $?PKGDECL := @?PKGDECL[0];
+
+    if $key eq 'panic' {
+        $/.panic("Unable to parse " ~ $?PKGDECL ~ " definition");
+    }
+
+    my $past := $( $/{$key} );
+    $past.blocktype('declaration');
+
+    if $key eq 'block' {
+        # A normal block acts like a BEGIN and is executed ASAP.
+        $past.pirflags(':load :init');
+    }
+    elsif $key eq 'statement_block' {
+        unless ~$<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 );
+
+    #  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('!class_create'), $?PKGDECL, 
~$<module_name>[0])
+        )
+    );
+
+    #  Add any traits coming from the package declarator.
+    #  Traits in the body have already been added to the block.
+    my $metaclass := PAST::Var.new( :name('metaclass'), :scope('register') );
+    if $<trait> {
+        for @($<trait>) {
+            #  Trait nodes come in as PAST::Op( :name('list') ).
+            #  We just modify them to call !class_trait and add
+            #  the metaclass as the first argument.
+            my $trait := $( $_ );
+            $trait.name('!class_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('!class_compose'), $metaclass) );
+
+    make $past;
 }
 
 

Modified: branches/rvar/languages/perl6/src/parser/grammar.pg
==============================================================================
--- branches/rvar/languages/perl6/src/parser/grammar.pg (original)
+++ branches/rvar/languages/perl6/src/parser/grammar.pg Thu Jan  1 10:37:19 2009
@@ -615,10 +615,10 @@
     ]? 
     <trait>*
     [
-    | ';' <statement_block>
-    | <block>
+    | ';' <statement_block> {*}                          #= statement_block
+    | <block> {*}                                        #= block
+    | {*}                                                #= panic
     ]
-    {*}
 }
 
 

Reply via email to