Author: jonathan
Date: Tue Jan 20 06:20:29 2009
New Revision: 35806

Modified:
   trunk/languages/perl6/src/classes/Role.pir

Log:
[rakudo] Make a role pun a class when you call .new on it.

Modified: trunk/languages/perl6/src/classes/Role.pir
==============================================================================
--- trunk/languages/perl6/src/classes/Role.pir  (original)
+++ trunk/languages/perl6/src/classes/Role.pir  Tue Jan 20 06:20:29 2009
@@ -166,6 +166,23 @@
 .end
 
 
+=item new
+
+Puns the role and instantiates the punned class.
+
+=cut
+
+.sub 'new' :method
+    .param pmc pos_args  :slurpy
+    .param pmc name_args :slurpy :named
+
+    # Must be argument-less case of the role; select that and then tailcall
+    # it's new.
+    $P0 = self.'!select'()
+    .tailcall $P0.'new'(pos_args :flat, name_args :flat :named)
+.end
+
+
 =item elements (vtable method)
 
 Gives the number of possible parameterized roles we can select from (but really
@@ -182,6 +199,60 @@
 
 =back
 
+=head1 Methods on Parrot Roles
+
+We also add some methods to the Parrot roles.
+
+=item new
+
+Puns the role to a class and instantiates it.
+
+=cut
+
+.namespace ["Role"]
+.sub 'new' :method
+    .param pmc pos_args    :slurpy
+    .param pmc name_args   :slurpy :named
+
+    # See if we have already created a punned class; use it if so.
+    .local pmc pun
+    pun = getprop '$!pun', self
+    if null pun goto make_pun
+    .tailcall pun.'new'(pos_args :flat, name_args :flat :named)
+  make_pun:
+
+    # Otherwise, need to create a punned class.
+    .local pmc p6meta, metaclass, proto
+    p6meta = get_hll_global ['Perl6Object'], '$!P6META'
+    metaclass = new ['Class']
+    $P0 = box 'class'
+    setprop metaclass, 'pkgtype', $P0
+    metaclass.'add_role'(self)
+    # XXX Would be nice to call !meta_compose here; for some reason, Parrot
+    # ends up calling the wrong multi-variant. Something to investigate, when
+    # I/someone has the energy for it.
+    '!compose_role_attributes'(metaclass, self)
+    proto = p6meta.'register'(metaclass, 'parent'=>'Any')
+
+    # Stash it away, then instantiate it.
+    setprop self, '$!pun', proto
+    .tailcall proto.'new'(pos_args :flat, name_args :flat :named)
+.end
+
+
+=item ACCEPTS
+
+=cut
+
+.sub 'ACCEPTS' :method
+    .param pmc topic
+    $I0 = does topic, self
+    $P0 = 'prefix:?'($I0)
+    .return ($P0)
+.end
+
+=back
+
 =cut
 
 # Local Variables:

Reply via email to