cvsuser     05/03/16 06:21:34

  Modified:    classes  fixedpmcarray.pmc
               src      mmd.c
  Log:
  MMD 4 - more pieces; array sort
  
  * more MMD stuff - search classes
  * rewrite fixedpmcarray.quicksort
  
  Revision  Changes    Path
  1.31      +60 -88    parrot/classes/fixedpmcarray.pmc
  
  Index: fixedpmcarray.pmc
  ===================================================================
  RCS file: /cvs/public/parrot/classes/fixedpmcarray.pmc,v
  retrieving revision 1.30
  retrieving revision 1.31
  diff -u -r1.30 -r1.31
  --- fixedpmcarray.pmc 9 Mar 2005 14:51:58 -0000       1.30
  +++ fixedpmcarray.pmc 16 Mar 2005 14:21:33 -0000      1.31
  @@ -1,6 +1,6 @@
   /*
   Copyright: 2001-2003 The Perl Foundation.  All Rights Reserved.
  -$Id: fixedpmcarray.pmc,v 1.30 2005/03/09 14:51:58 leo Exp $
  +$Id: fixedpmcarray.pmc,v 1.31 2005/03/16 14:21:33 leo Exp $
   
   =head1 NAME
   
  @@ -21,111 +21,83 @@
   
   #include "parrot/parrot.h"
   
  -/*
  - * need this as long this hack is using qsort
  - */
  -static Interp* the_interp;
  -static PMC* sort_cmp_pmc;
  +static void
  +swap(void **x, void **y)
  +{
  +    void *t = *x;
  +    *x = *y;
  +    *y = t;
  +}
   
  -static int
  -sort_compare(void *a, void *b)
  +typedef INTVAL (*sort_func_t)(Interp *, void*, void*);
  +
  +static INTVAL
  +COMPARE(Interp *interpreter, void *a, void *b, PMC *cmp)
   {
  -    PMC *pa = *(PMC**)a;
  -    PMC *pb = *(PMC**)b;
  -    return mmd_dispatch_i_pp(the_interp, pa, pb, MMD_CMP);
  +    if (!cmp)
  +        return mmd_dispatch_i_pp(interpreter, a, b, MMD_CMP);
  +    if (cmp->vtable->base_type == enum_class_NCI) {
  +        sort_func_t f = (sort_func_t)D2FPTR(PMC_struct_val(cmp));
  +        return f(interpreter, a, b);
  +    }
  +    return Parrot_runops_fromc_args_reti(interpreter, cmp, "IPP", a, b);
   }
   
  -static int
  -sort_ext_compare(void *a, void *b)
  +static void
  +quicksort(Interp *interpreter, void **data, UINTVAL n, PMC *cmp)
   {
  -    PMC *pa = *(PMC**)a;
  -    PMC *pb = *(PMC**)b;
  -    return Parrot_runops_fromc_args_reti(the_interp,
  -        sort_cmp_pmc, "IPP", pa, pb);
  +    UINTVAL i, j, ln, rn;
  +
  +    while (n > 1) {
  +        swap(&data[0], &data[n/2]);
  +        for (i = 0, j = n; ; ) {
  +            do
  +                --j;
  +            while (COMPARE(interpreter, data[j], data[0], cmp) > 0);
  +            do
  +                ++i;
  +            while (i < j && COMPARE(interpreter, data[i], data[0], cmp) < 0);
  +            if (i >= j)
  +                break;
  +            swap(&data[i], &data[j]);
  +        }
  +        swap(&data[j], &data[0]);
  +        ln = j;
  +        rn = n - ++j;
  +        if (ln < rn) {
  +            quicksort(interpreter, data, ln, cmp);
  +            data += j;
  +            n = rn;
  +        }
  +        else {
  +            quicksort(interpreter, data + j, rn, cmp);
  +            n = ln;
  +        }
  +    }
   }
   
   pmclass FixedPMCArray need_ext does array {
   
   /*
   
  -=item C<void* sort(PMC* cmp_func)>
  +=item C<METHOD void sort(PMC* cmp_func)>
   
   Sort this array, optionally using the provided cmp_func
   
   =cut
   
   */
  +
   METHOD void sort(PMC *cmp_func) {
  -    int (*func)(void*, void*);
  -    PMC *first;
  -    INTVAL type;
  -    PMC *s;
  -
  -    the_interp = INTERP;
  -    if (REG_INT(3) == 0) {
  -        first = ((PMC**)PMC_data(SELF))[0];
  -        /* XXX simulate MMD inheritance: Int isa TT */
  -        type = first->vtable->base_type - 1;
  -        s = mmd_vtfind(INTERP, MMD_CMP, type, 0);
  -        /* cmp was overriden ? */
  -        if (s->vtable->base_type == enum_class_Sub) {
  -            cmp_func = s;
  -            goto use_sub;
  -        }
  -default_sort:
  -        func = sort_compare;
  -use_func:
  -        qsort(PMC_data(SELF), PMC_int_val(SELF), sizeof(PMC *),
  -                (int (*)(const void*, const void*))func);
  -    }
  -    else {
  -        void *regs;
  -        int run_core;
  -        /*
  -         * cmp_func is a PASM PMC
  -         * TODO check, if it's NCI
  -         */
  -use_sub:
  -        run_core = INTERP->run_core;
  -        if (PMC_IS_NULL(cmp_func) ||
  -                cmp_func == Parrot_base_vtables[enum_class_None]->class) {
  -            /* a NULL or None PMC was passed
  -            */
  -            goto default_sort;
  -        }
  -        else {
  -            if (cmp_func->vtable->base_type == enum_class_NCI) {
  -                /* the C function inside is at struct_val
  -                 * hopefully this function does compare
  -                 */
  -                func = (int (*)(void*, void*)) PMC_struct_val(cmp_func);
  -                /*
  -                 * XXX not yet -cmp doesn't take an interpreter arg
  -                 */
  -                /* goto use_func; */
  -                goto default_sort;
  -            }
  -        }
  -        /*
  -         * save registers once, as the compare function will be called
  -         * repeatedly
  -         */
  -        func = sort_ext_compare;
  -        sort_cmp_pmc = cmp_func;
  -        /*
  -         * TODO fix errors with JIT or prederefed core
  -         */
  -        if (run_core == PARROT_JIT_CORE) {
  -#ifdef HAVE_COMPUTED_GOTO
  -            INTERP->run_core = PARROT_CGOTO_CORE;
  -#else
  -            INTERP->run_core = PARROT_FAST_CORE;
  -#endif
  -        }
  -        qsort(PMC_data(SELF), PMC_int_val(SELF), sizeof(PMC *),
  -                (int (*)(const void*, const void*))func);
  -        INTERP->run_core = run_core;
  -    }
  +    UINTVAL n;
  +
  +
  +    n = (UINTVAL) PMC_int_val(SELF);
  +    if (n <= 1)
  +        return;
  +    if (REG_INT(3) == 0)
  +        cmp_func = NULL;
  +    quicksort(interpreter, PMC_data(SELF), n, cmp_func);
   }
   
   /*
  
  
  
  1.52      +104 -4    parrot/src/mmd.c
  
  Index: mmd.c
  ===================================================================
  RCS file: /cvs/public/parrot/src/mmd.c,v
  retrieving revision 1.51
  retrieving revision 1.52
  diff -u -r1.51 -r1.52
  --- mmd.c     14 Mar 2005 14:45:40 -0000      1.51
  +++ mmd.c     16 Mar 2005 14:21:34 -0000      1.52
  @@ -1,6 +1,6 @@
   /*
   Copyright: 2003 The Perl Foundation.  All Rights Reserved.
  -$Id: mmd.c,v 1.51 2005/03/14 14:45:40 leo Exp $
  +$Id: mmd.c,v 1.52 2005/03/16 14:21:34 leo Exp $
   
   =head1 NAME
   
  @@ -663,10 +663,13 @@
   static PMC* mmd_arg_tuple_func(Interp *, STRING *signature, va_list args);
   static PMC* mmd_search_default(Interp *, STRING *meth, PMC *arg_tuple);
   static PMC* mmd_search_scopes(Interp *, STRING *meth, PMC *arg_tuple);
  +static void mmd_search_classes(Interp *, STRING *meth, PMC *arg_tuple, PMC 
*);
   static int  mmd_search_lexical(Interp *, STRING *meth, PMC *arg_tuple, PMC 
*);
   static int  mmd_search_package(Interp *, STRING *meth, PMC *arg_tuple, PMC 
*);
   static int  mmd_search_global(Interp *, STRING *meth, PMC *arg_tuple, PMC *);
   static int  mmd_search_builtin(Interp *, STRING *meth, PMC *arg_tuple, PMC 
*);
  +static int  mmd_maybe_candidate(Interp *, PMC *pmc, PMC *arg_tuple, PMC *cl);
  +static void mmd_sort_candidates(Interp *, PMC *arg_tuple, PMC *cl);
   
   /*
   
  @@ -705,7 +708,9 @@
       va_start(args, signature);
       arg_tuple = mmd_arg_tuple_inline(interpreter, signature, args);
       va_end(args);
  -
  +    /*
  +     * default search policy
  +     */
       return mmd_search_default(interpreter, meth, arg_tuple);
   }
   
  @@ -778,10 +783,104 @@
   static PMC*
   mmd_search_default(Interp *interpreter, STRING *meth, PMC *arg_tuple)
   {
  -    PMC *candidate_list;
  +    PMC *candidate_list, *pmc;
  +    INTVAL i, n;
  +    STRING *_sub;
   
  +    /*
  +     * 2) create a list of matching functions
  +     */
       candidate_list = mmd_search_scopes(interpreter, meth, arg_tuple);
  -    return NULL;
  +    /*
  +     * 3) if list is empty fail
  +     *    if the first found function is a plain Sub: finito
  +     */
  +    n = VTABLE_elements(interpreter, candidate_list);
  +    if (!n)
  +        return NULL;
  +    pmc = VTABLE_get_pmc_keyed_int(interpreter, candidate_list, 0);
  +    _sub = CONST_STRING(interpreter, "Sub");
  +
  +    if (VTABLE_isa(interpreter, pmc, _sub)) {
  +        return pmc;
  +    }
  +    /*
  +     * 4) first is a MultiSub - go through all found MultiSubs and check
  +     *    the first arguments MRO, add all MultiSubs and plain methods,
  +     *    where the first argument matches
  +     */
  +    mmd_search_classes(interpreter, meth, arg_tuple, candidate_list);
  +    /*
  +     * 5) sort the list
  +     */
  +    mmd_sort_candidates(interpreter, arg_tuple, candidate_list);
  +    /*
  +     * 6) Uff, return first one
  +     */
  +    pmc = VTABLE_get_pmc_keyed_int(interpreter, candidate_list, 0);
  +    return pmc;
  +}
  +
  +/*
  +
  +=item C<static void mmd_search_classes(Interp *, STRING *meth, PMC 
*arg_tuple, PMC *cl)>
  +
  +Search all the classes in all MultiSubs of the candidates C<cl> and return
  +a list of all candidates.
  +
  +*/
  +
  +static void
  +mmd_search_classes(Interp *interpreter, STRING *meth, PMC *arg_tuple, PMC 
*cl)
  +{
  +    PMC *pmc, *mro, *class;
  +    INTVAL i, n, type1;
  +    STRING *namespace_name;
  +
  +    /*
  +     * get the class of the first argument
  +     */
  +    type1 = VTABLE_get_integer_keyed_int(interpreter, arg_tuple, 0);
  +    if (type1 < 0) {
  +        internal_exception(1, "unimplemted native MMD type");
  +        /* TODO create some class namespace */
  +    }
  +    else {
  +        mro = Parrot_base_vtables[type1]->mro;
  +        n = VTABLE_elements(interpreter, mro);
  +        for (i = 0; i < n; ++i) {
  +            class = VTABLE_get_pmc_keyed_int(interpreter, mro, i);
  +            namespace_name = VTABLE_namespace_name(interpreter, class);
  +            pmc = Parrot_find_global(interpreter, namespace_name, meth);
  +            if (pmc) {
  +                /*
  +                 * mmd_is_hidden would consider all previous candidates
  +                 * XXX pass current n so that only candidates from this
  +                 *     mro are used?
  +                 */
  +                if (mmd_maybe_candidate(interpreter, pmc, arg_tuple, cl))
  +                    break;
  +            }
  +        }
  +    }
  +    return cl;
  +}
  +
  +/*
  +
  +=item C<static void mmd_sort_candidates(Interp *, PMC *arg_tuple, PMC *cl)>
  +
  +Sort the candidate list C<cl> by Manhattan Distance
  +
  +*/
  +
  +static void
  +mmd_sort_candidates(Interp *interpreter, PMC *arg_tuple, PMC *cl)
  +{
  +    INTVAL n;
  +
  +    n = VTABLE_elements(interpreter, cl);
  +
   }
   
   /*
  @@ -862,6 +961,7 @@
       if (VTABLE_isa(interpreter, pmc, _sub)) {
           /* a plain sub stops outer searches */
           /* TODO check arity of sub */
  +
           VTABLE_push_pmc(interpreter, cl, pmc);
           return 1;
       }
  
  
  

Reply via email to