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 */
/*