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;
   }
   
  
  
  

Reply via email to