Author: jonathan
Date: Thu Mar 15 15:55:20 2007
New Revision: 17513

Modified:
   trunk/src/pmc/metaclass.pmc
   trunk/src/pmc/object.pmc
   trunk/src/pmc/role.pmc

Log:
[PDD15]: Add add_method methods to the MetaClass and Role PMCs, method lookup 
in the MetaClass PMC and implement find_method in the Object PMC. That means 
you can add methods and do method calls. Please note that add_method is not 
specified yet (thus no spec tests have been added for it), and if the spec is 
different it will change.

Modified: trunk/src/pmc/metaclass.pmc
==============================================================================
--- trunk/src/pmc/metaclass.pmc (original)
+++ trunk/src/pmc/metaclass.pmc Thu Mar 15 15:55:20 2007
@@ -391,7 +391,7 @@
 =cut
 
 */
-    PMETHOD void add_parent(PMC* parent) {
+    PMETHOD void add_parent(PMC *parent) {
         Parrot_MetaClass *class = PARROT_METACLASS(SELF);
 
         /* If we've been instantiated already, need a new class. */
@@ -413,6 +413,30 @@
         VTABLE_push_pmc(interp, class->parents, parent);
     }
 
+/*
+
+=item C<void add_method(STRING *name, PMC *sub)>
+
+Adds the given sub PMC as a method with the given name.
+
+=cut
+
+*/
+    PMETHOD void add_method(STRING *name, PMC *sub)
+    {
+        Parrot_MetaClass *class = PARROT_METACLASS(SELF);
+
+        /* If we have already added a method with this name... */
+        if (VTABLE_exists_keyed_str(interp, class->methods, name)) {
+            /* XXX Need to handle multi methods here. */
+            real_exception(interp, NULL, E_NotImplementedError,
+                "Currently, adding multiple methods of the same name is not 
supported.");
+        }
+        else {
+            /* Enter it into the table. */
+            VTABLE_set_pmc_keyed_str(interp, class->methods, name, sub);
+        }
+    }
 
 /*
 
@@ -479,6 +503,38 @@
         preturn(int index);
     }
 
+/*
+
+=item C<void _get_method_pmc(STRING *name)>
+
+This walks the method resolution order and tries to locate a method of the
+give name. Returns the first one it finds, or NULL if no method is found.
+This method is intended to be used by the Object PMC.
+
+=cut
+
+*/
+    PMETHOD void _get_method_pmc(STRING *name) {
+        Parrot_MetaClass *class = PARROT_METACLASS(SELF);
+
+        /* Walk and search. */
+        PMC *found = NULL;
+        int num_classes = VTABLE_elements(interp, class->all_parents);
+        int i;
+        for (i = 0; i < num_classes; i++) {
+            /* Get the class and see if it has the method. */
+            PMC *cur_class = VTABLE_get_pmc_keyed_int(interp, 
class->all_parents, i);
+            Parrot_MetaClass *class_info = PARROT_METACLASS(cur_class);
+            if (VTABLE_exists_keyed_str(interp, class_info->methods, name)) {
+                /* Found it! */
+                found = VTABLE_get_pmc_keyed_str(interp, class_info->methods, 
name);
+            }
+        }
+
+        preturn(PMC *found);
+    }
+
+
 } /* END pmclass */
 
 /*

Modified: trunk/src/pmc/object.pmc
==============================================================================
--- trunk/src/pmc/object.pmc    (original)
+++ trunk/src/pmc/object.pmc    Thu Mar 15 15:55:20 2007
@@ -136,6 +136,25 @@
         }
     }
 
+/*
+
+=item C<PMC* find_method(STRING *method_name)>
+
+Walks the MRO of the class and finds the method with the given name.
+
+=cut
+
+*/
+    PMC* find_method(STRING *method_name)
+    {
+        /* Use the class to look up the method. One day, we'll use the 
cache... */
+        Parrot_Object *obj = PARROT_OBJECT(SELF);
+        PMC *class = obj->class;
+        PMC *method = NULL;
+        (PMC *method) = PMINVOKE(interp, class, "_get_method_pmc", STRING* 
method_name);
+        return method;
+    }
+
 }
 
 /*

Modified: trunk/src/pmc/role.pmc
==============================================================================
--- trunk/src/pmc/role.pmc      (original)
+++ trunk/src/pmc/role.pmc      Thu Mar 15 15:55:20 2007
@@ -235,6 +235,31 @@
         preturn(PMC *ret_roles);
     }
 
+/*
+
+=item C<void add_method(STRING *name, PMC *sub)>
+
+Adds the given sub PMC as a method with the given name.
+
+=cut
+
+*/
+    PMETHOD void add_method(STRING *name, PMC *sub)
+    {
+        Parrot_Role *role = PARROT_ROLE(SELF);
+
+        /* If we have already added a method with this name... */
+        if (VTABLE_exists_keyed_str(interp, role->methods, name)) {
+            /* XXX Need to handle multi methods here. */
+            real_exception(interp, NULL, E_NotImplementedError,
+                "Currently, adding multiple methods of the same name is not 
supported.");
+        }
+        else {
+            /* Enter it into the table. */
+            VTABLE_set_pmc_keyed_str(interp, role->methods, name, sub);
+        }
+    }
+
 } /* END pmclass */
 
 /*

Reply via email to