Author: jonathan
Date: Tue Apr 3 17:17:29 2007
New Revision: 17966
Modified:
trunk/src/pmc/class.pmc
Log:
[PDD15]: Reogranize Class PMC to separate out methods and vtable methods.
Implement add_method vtable method and make the PCCMETHOD add_method call it.
Modified: trunk/src/pmc/class.pmc
==============================================================================
--- trunk/src/pmc/class.pmc (original)
+++ trunk/src/pmc/class.pmc Tue Apr 3 17:17:29 2007
@@ -218,67 +218,41 @@
pobject_lives(interp, (PObj*)class->resolve);
}
-
-/*
-
-=item C<void attributes()>
-
-Return a hash where the keys are attribute names and the values are hashes
-providing a set of key/value pairs describing the attribute.
-
-=cut
-
-*/
- PCCMETHOD void attributes() {
- Parrot_Class *class = PARROT_CLASS(SELF);
- PMC *ret_attrib_metadata = VTABLE_clone(interp,
class->attrib_metadata);
- PCCRETURN(PMC *ret_attrib_metadata);
- }
-
-
/*
-=item C<void add_attribute()>
+=item C<void add_method(STRING *name, PMC *sub)>
-Add an attribute to the class. Requires a name and, optionally, a type.
+Adds the given sub PMC as a method with the given name.
=cut
*/
- PCCMETHOD void add_attribute(STRING *attribute_name,
- STRING* attribute_type :optional, int got_type :opt_flag) {
+ void add_method(STRING *name, PMC *sub)
+ {
Parrot_Class *class = PARROT_CLASS(SELF);
- PMC *new_attribute = pmc_new(interp, enum_class_Hash);
- /* If we've been instantiated already, need a new class. */
- if (class->instantiated) {
- /* XXX Unimplemented! */
+ /* 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,
- "Modifications to already instantiated classes not allowed
yet.");
+ "A method of this name already exists. It may have been
supplied by a role.");
}
-
- /* If we've already got an attribute of this name, it's an error. */
- if (VTABLE_exists_keyed_str(interp, class->attrib_metadata,
attribute_name)) {
- real_exception(interp, NULL, INVALID_OPERATION,
- "An attribute of this name already exists.");
- return;
+ else {
+ /* Enter it into the table. */
+ VTABLE_set_pmc_keyed_str(interp, class->methods, name, sub);
}
+ }
- /* Set name and type. */
- VTABLE_set_string_keyed_str(interp, new_attribute,
- CONST_STRING(interp, "name"), attribute_name);
- if (got_type) {
- VTABLE_set_string_keyed_str(interp, new_attribute,
- CONST_STRING(interp, "type"), attribute_type);
- }
- /* Enter the attribute in the attributes array. */
- VTABLE_set_pmc_keyed_str(interp, class->attrib_metadata,
attribute_name, new_attribute);
- }
+ /* **********************************************************************
+ /* Below here are non-vtable methods that eventually will go in a role
+ * that is composed into here to optionally give a nice interface from
+ * PIR (ParrotClass isa Class does ClassMethods or something like this).
+ * **********************************************************************/
/*
-=item C<void name()>
+=item C<void name(STRING *name :optional, int got_name :opt_flag)>
Sets the name of the class.
@@ -300,7 +274,7 @@
/*
-=item C<void namespace()>
+=item C<void namespace(PMC *namespace :optional, int got_name :opt_flag)>
With a parameter, sets the namespace for the class. Expects a fully
qualified namespace to be specified as a key. If you already have linked
another
@@ -423,76 +397,136 @@
PCCRETURN(PMC *obj)
}
-
/*
-=item C<void parents()>
+=item C<void attributes()>
-Return the parents array PMC.
+Return a hash where the keys are attribute names and the values are hashes
+providing a set of key/value pairs describing the attribute.
=cut
*/
- PCCMETHOD void parents() {
+ PCCMETHOD void attributes() {
Parrot_Class *class = PARROT_CLASS(SELF);
- PMC *ret_parents = VTABLE_clone(interp, class->parents);
- PCCRETURN(PMC *ret_parents);
+ PMC *ret_attrib_metadata = VTABLE_clone(interp,
class->attrib_metadata);
+ PCCRETURN(PMC *ret_attrib_metadata);
}
/*
-=item C<void add_parent(PMC *parent)>
+=item C<void add_attribute()>
-Return the parents array PMC.
+Add an attribute to the class. Requires a name and, optionally, a type.
=cut
*/
- PCCMETHOD void add_parent(PMC *parent) {
+ PCCMETHOD void add_attribute(STRING *attribute_name,
+ STRING* attribute_type :optional, int got_type :opt_flag) {
Parrot_Class *class = PARROT_CLASS(SELF);
+ PMC *new_attribute = pmc_new(interp, enum_class_Hash);
/* If we've been instantiated already, need a new class. */
if (class->instantiated) {
/* XXX Unimplemented! */
real_exception(interp, NULL, E_NotImplementedError,
"Modifications to already instantiated classes not allowed
yet.");
- return;
}
- /* Ensure it really is a class. */
- if (!PObj_is_class_TEST(parent)) {
- real_exception(interp, NULL, E_TypeError,
- "You can only add a class as a parent to another class.");
+ /* If we've already got an attribute of this name, it's an error. */
+ if (VTABLE_exists_keyed_str(interp, class->attrib_metadata,
attribute_name)) {
+ real_exception(interp, NULL, INVALID_OPERATION,
+ "An attribute of this name already exists.");
return;
}
- /* Add to the list of our immediate parents. */
- VTABLE_push_pmc(interp, class->parents, parent);
+ /* Set name and type. */
+ VTABLE_set_string_keyed_str(interp, new_attribute,
+ CONST_STRING(interp, "name"), attribute_name);
+ if (got_type) {
+ VTABLE_set_string_keyed_str(interp, new_attribute,
+ CONST_STRING(interp, "type"), attribute_type);
+ }
+
+ /* Enter the attribute in the attributes array. */
+ VTABLE_set_pmc_keyed_str(interp, class->attrib_metadata,
attribute_name, new_attribute);
+ }
+
+/*
+
+=item C<void methods()>
+
+Return a hash where the keys are method names and the values are methods.
+
+=cut
+
+*/
+ PCCMETHOD void methods() {
+ Parrot_Class *class = PARROT_CLASS(SELF);
+ PMC *ret_methods = VTABLE_clone(interp, class->methods);
+ PCCRETURN(PMC *ret_methods);
}
/*
=item C<void add_method(STRING *name, PMC *sub)>
-Adds the given sub PMC as a method with the given name.
+Adds the given sub PMC as a method with the given name. Delegates to the
+C<add_method> vtable method.
=cut
*/
PCCMETHOD void add_method(STRING *name, PMC *sub)
{
+ VTABLE_add_method(interp, SELF, name, sub);
+ }
+
+/*
+
+=item C<void parents()>
+
+Return the parents array PMC.
+
+=cut
+
+*/
+ PCCMETHOD void parents() {
Parrot_Class *class = PARROT_CLASS(SELF);
+ PMC *ret_parents = VTABLE_clone(interp, class->parents);
+ PCCRETURN(PMC *ret_parents);
+ }
- /* 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. */
+/*
+
+=item C<void add_parent(PMC *parent)>
+
+Return the parents array PMC.
+
+=cut
+
+*/
+ PCCMETHOD void add_parent(PMC *parent) {
+ Parrot_Class *class = PARROT_CLASS(SELF);
+
+ /* If we've been instantiated already, need a new class. */
+ if (class->instantiated) {
+ /* XXX Unimplemented! */
real_exception(interp, NULL, E_NotImplementedError,
- "A method of this name already exists. It may have been
supplied by a role.");
+ "Modifications to already instantiated classes not allowed
yet.");
+ return;
}
- else {
- /* Enter it into the table. */
- VTABLE_set_pmc_keyed_str(interp, class->methods, name, sub);
+
+ /* Ensure it really is a class. */
+ if (!PObj_is_class_TEST(parent)) {
+ real_exception(interp, NULL, E_TypeError,
+ "You can only add a class as a parent to another class.");
+ return;
}
+
+ /* Add to the list of our immediate parents. */
+ VTABLE_push_pmc(interp, class->parents, parent);
}
/*