Author: leo
Date: Sun Jul 31 07:19:12 2005
New Revision: 8756

Added:
   trunk/classes/super.pmc   (contents, props changed)
Modified:
   trunk/MANIFEST
   trunk/t/pmc/object-meths.t
Log:
new Super PMC

* a Super PMC binds an object to SELF and redirects method lookup
  to the parent of the object's class
* see also perldoc classes/super.pmc

Please make realclean ...


Modified: trunk/MANIFEST
==============================================================================
--- trunk/MANIFEST      (original)
+++ trunk/MANIFEST      Sun Jul 31 07:19:12 2005
@@ -124,6 +124,7 @@ classes/slice.pmc                       
 classes/string.pmc                                []
 classes/stringarray.pmc                           []
 classes/sub.pmc                                   []
+classes/super.pmc                                 []
 classes/timer.pmc                                 []
 classes/tqueue.pmc                                []
 classes/undef.pmc                                                []

Added: trunk/classes/super.pmc
==============================================================================
--- (empty file)
+++ trunk/classes/super.pmc     Sun Jul 31 07:19:12 2005
@@ -0,0 +1,137 @@
+/*
+Copyright: 2005 The Perl Foundation.  All Rights Reserved.
+$Id$
+
+=head1 NAME
+
+classes/super.pmc - Super Class
+
+=head1 DESCRIPTION
+
+A Super PMC holds an object and redirects method lookup to the parent
+of the object's class.
+
+=head1 SYNOPSIS
+
+  .sub meth method
+      .local pmc s
+      s = new .Super, self
+      s."meth"()
+  .end
+
+=head2 Methods
+
+=over 4
+
+=cut
+
+*/
+
+#include "parrot/parrot.h"
+#include "parrot/method_util.h"
+
+pmclass Super need_ext {
+
+/*
+
+=item C<void init(PMC *obj)>
+
+Create an unbound super instance.
+
+=item C<void init_pmc(PMC *obj)>
+
+Initialize a new super instance, bound to the C<obj>.
+
+=item C<void set_pmc(PMC *obj)>
+
+Bind the object C<obj> to this Super instance.
+
+=item C<PMC* get_pmc(void)>
+
+Return the bound object.
+
+=item C<void mark()>
+
+Set the bound object live.
+
+=item C<PMC *find_method(STRING *name)>
+
+Find the method for C<*name> in the parent class of the bound object.
+
+=cut
+
+*/
+
+    void init() {
+       PMC_pmc_val(SELF) = PMC_struct_val(SELF) = PMCNULL;
+    }
+
+    void init_pmc(PMC *obj) {
+       PMC_struct_val(SELF) = PMCNULL;
+       SELF.set_pmc(obj);
+    }
+
+    void set_pmc(PMC *obj) {
+        PMC_pmc_val(SELF) = obj;
+        if (!PMC_IS_NULL(obj)) {
+           PMC *mro = obj->vtable->mro;
+           if (VTABLE_elements(INTERP, mro) <= 1)
+               real_exception(INTERP, NULL, E_TypeError,
+                        "object has no parent");
+            PObj_custom_mark_SET(SELF);
+        }
+    }
+
+    PMC* get_pmc() {
+        return PMC_pmc_val(SELF);
+    }
+
+
+    void mark() {
+        if (PMC_pmc_val(SELF))
+            pobject_lives(INTERP, (PObj *)PMC_pmc_val(SELF));
+       if (PMC_struct_val(SELF))
+           pobject_lives(INTERP, (PObj *)PMC_struct_val(SELF));
+    }
+
+    PMC* find_method(STRING* name) {
+        PMC *obj, *mro, *class;
+
+        obj = PMC_pmc_val(SELF);
+        if (PMC_IS_NULL(obj)) {
+               real_exception(INTERP, NULL, E_TypeError,
+                        "no object bound to super");
+        }
+        interpreter->ctx.current_object = obj;
+        mro = obj->vtable->mro;
+        class = VTABLE_get_pmc_keyed_int(INTERP, mro, 1);
+        return VTABLE_find_method(INTERP, class, name);
+    }
+}
+
+/*
+
+=back
+
+=head1 SEE ALSO
+
+F<classes/parrotobject.pmc>
+
+=head1 HISTORY
+
+Initial revision by leo 2005.07.31.
+
+=cut
+
+*/
+
+/*
+ * Local variables:
+ * c-indentation-style: bsd
+ * c-basic-offset: 4
+ * indent-tabs-mode: nil
+ * End:
+ *
+ * vim: expandtab shiftwidth=4:
+*/
+

Modified: trunk/t/pmc/object-meths.t
==============================================================================
--- trunk/t/pmc/object-meths.t  (original)
+++ trunk/t/pmc/object-meths.t  Sun Jul 31 07:19:12 2005
@@ -16,7 +16,7 @@ Tests PMC object methods.
 
 =cut
 
-use Parrot::Test tests => 30;
+use Parrot::Test tests => 31;
 use Test::More;
 
 output_like(<<'CODE', <<'OUTPUT', "callmethod - unknown method");
@@ -978,4 +978,34 @@ CODE
 foofoo
 OUTPUT
 
+pir_output_is(<<'CODE', <<'OUTPUT', "super 1");
+.sub main @MAIN
+    .local pmc o, cl
+    cl = newclass 'Parent'
+    cl = subclass cl, 'Child'
+    o = new 'Child'
+    o."foo"()
+.end
+
+.namespace ['Parent']
+.sub foo method
+    print "Parent foo\n"
+    self."bar"()
+.end
+.sub bar method
+    print "Parent bar\n"
+.end
+
+.namespace ['Child']
+.sub foo method
+    print "Child foo\n"
+    .local pmc s
+    s = new .Super, self
+    s."foo"()
+.end
+CODE
+Child foo
+Parent foo
+Parent bar
+OUTPUT
 

Reply via email to