cvsuser 04/02/24 09:59:46
Modified: src objects.c
Log:
Classes can now have multiple parents
Revision Changes Path
1.34 +101 -4 parrot/src/objects.c
Index: objects.c
===================================================================
RCS file: /cvs/public/parrot/src/objects.c,v
retrieving revision 1.33
retrieving revision 1.34
diff -u -w -r1.33 -r1.34
--- objects.c 24 Feb 2004 15:07:21 -0000 1.33
+++ objects.c 24 Feb 2004 17:59:46 -0000 1.34
@@ -1,6 +1,6 @@
/*
Copyright: 2001-2003 The Perl Foundation. All Rights Reserved.
-$Id: objects.c,v 1.33 2004/02/24 15:07:21 dan Exp $
+$Id: objects.c,v 1.34 2004/02/24 17:59:46 dan Exp $
=head1 NAME
@@ -335,15 +335,112 @@
Parrot_add_parent(Parrot_Interp interpreter, PMC *new_base_class,
PMC *existing_class)>
-This currently does nothing but return C<NULL>.
+Add the parent class to the current class' parent list. This also
+involved adding all the parent's parents, as well as all attributes of
+the parent classes that we're adding in.
=cut
*/
PMC *
-Parrot_add_parent(Parrot_Interp interpreter, PMC *new_base_class,
- PMC *existing_class) {
+Parrot_add_parent(Parrot_Interp interpreter, PMC *current_class_obj,
+ PMC *add_on_class_obj) {
+ PMC *current_class;
+ PMC *add_on_class;
+ PMC *current_class_array;
+ PMC *current_parent_array;
+ PMC *add_on_class_array;
+ INTVAL current_count, add_on_count, current_offset, add_on_offset;
+ INTVAL current_size;
+ INTVAL already_in = 0;
+
+ /* Grab the useful stuff from the guts of the class PMC */
+ current_class = PMC_data(current_class_obj);
+ add_on_class = PMC_data(add_on_class_obj);
+
+ /* Start with the current list */
+ current_class_array = VTABLE_get_pmc_keyed_int(interpreter, current_class,
+ PCD_ALL_PARENTS);
+ add_on_class_array = VTABLE_get_pmc_keyed_int(interpreter, add_on_class,
+ PCD_ALL_PARENTS);
+ current_parent_array = VTABLE_get_pmc_keyed_int(interpreter, current_class,
+ PCD_PARENTS);
+
+ /* Tack on the new parent class to the end of the immediate parent
+ list */
+ current_size = VTABLE_elements(interpreter, current_parent_array);
+ VTABLE_set_integer_native(interpreter, current_parent_array,
+ current_size + 1);
+ VTABLE_set_pmc_keyed_int(interpreter, current_parent_array, current_size,
+ add_on_class);
+
+ /* Loop through them. We can assume that we can just tack on any
+ new classes to the end of the current class array. Attributes
+ are a bit more interesting, unfortunately */
+ current_count = VTABLE_elements(interpreter, current_class_array);
+ add_on_count = VTABLE_elements(interpreter, add_on_class_array);
+
+ /* Check to see if the parent class is already in the list. */
+ for (current_offset = 0;
+ current_offset < current_count;
+ current_offset++) {
+ if (add_on_class_obj == VTABLE_get_pmc_keyed_int(interpreter,
+ current_class_array,
+ current_offset)) {
+ already_in = 1;
+ puts("Already there");
+ }
+ }
+
+ /* If the parent class isn't already in the list (which can happen
+ in a MI situation) go loop through all the classes in the
+ parent list and add them into the child if they're not already
+ in the child list */
+ if (!already_in) {
+ INTVAL current_size;
+
+ /* First go put the new parent class on the search list */
+ current_size = VTABLE_elements(interpreter,
+ current_class_array);
+ VTABLE_set_integer_native(interpreter,
+ current_class_array,
+ current_size + 1);
+ VTABLE_set_pmc_keyed_int(interpreter, current_class_array,
+ current_size, add_on_class_obj);
+
+ /* And then go put all the parent class' parents on the list,
+ if they're not there already */
+ for (add_on_offset = 0; add_on_offset < add_on_count;
+ add_on_offset++) {
+ INTVAL found = 0;
+ PMC *potential = VTABLE_get_pmc_keyed_int(interpreter,
+ add_on_class_array,
+ add_on_offset);
+ for (current_offset = 0;
+ current_offset < current_count;
+ current_offset++) {
+ if (potential == VTABLE_get_pmc_keyed_int(interpreter,
+ current_class_array,
+ current_offset)) {
+ found = 1;
+ puts("Found it");
+ }
+ }
+ /* We found it. Yay us. Add the parent class to the list */
+ if (!found) {
+ INTVAL current_size;
+ current_size = VTABLE_elements(interpreter,
+ current_class_array);
+ VTABLE_set_integer_native(interpreter,
+ current_class_array,
+ current_size + 1);
+ VTABLE_set_pmc_keyed_int(interpreter, current_class_array,
+ current_size, potential);
+ puts("Adding it in");
+ }
+ }
+ }
return NULL;
}