cvsuser     05/03/30 03:12:36

  Modified:    include/parrot global.h
               ops      var.ops
               src      global.c mmd.c
               t/pmc    mmd.t
  Log:
  MMD 8 - dispatch on argument count
  
  * see note on p6i
  
  * implement Parrot_find_global_p function that
    searches in a namespace (key) PMC or in a Hash
  
  Revision  Changes    Path
  1.7       +3 -1      parrot/include/parrot/global.h
  
  Index: global.h
  ===================================================================
  RCS file: /cvs/public/parrot/include/parrot/global.h,v
  retrieving revision 1.6
  retrieving revision 1.7
  diff -u -r1.6 -r1.7
  --- global.h  30 Mar 2005 09:07:28 -0000      1.6
  +++ global.h  30 Mar 2005 11:12:32 -0000      1.7
  @@ -1,7 +1,7 @@
   /* global.h
    *  Copyright: 2004 The Perl Foundation.  All Rights Reserved.
    *  CVS Info
  - *     $Id: global.h,v 1.6 2005/03/30 09:07:28 leo Exp $
  + *     $Id: global.h,v 1.7 2005/03/30 11:12:32 leo Exp $
    *  Overview:
    *      Contains accessor functions for globals
    *  Data Structure and Algorithms:
  @@ -15,6 +15,8 @@
   
   PMC *Parrot_find_global(Interp *, STRING *class, STRING *name);
   PMC *Parrot_get_global(Interp *, STRING *class,  STRING *name, void *next);
  +PMC *Parrot_find_global_p(Interp *, PMC *ns, STRING *name);
  +PMC *Parrot_get_global_p(Interp *, PMC *ns,  STRING *name);
   PMC *Parrot_global_namespace(Interp *, PMC *globals, STRING *ns);
   void Parrot_store_global(Interp *, STRING *class, STRING *globalname, PMC 
*pmc);
   void Parrot_store_sub_in_namespace(Interp*, PMC* sub_pmc);
  
  
  
  1.28      +3 -16     parrot/ops/var.ops
  
  Index: var.ops
  ===================================================================
  RCS file: /cvs/public/parrot/ops/var.ops,v
  retrieving revision 1.27
  retrieving revision 1.28
  diff -u -r1.27 -r1.28
  --- var.ops   19 Mar 2005 16:20:11 -0000      1.27
  +++ var.ops   30 Mar 2005 11:12:34 -0000      1.28
  @@ -311,27 +311,14 @@
   }
   
   op find_global(out PMC, in PMC, in STR) {
  -    /* XXX: All globals should go through an API */
       opcode_t * next;
  -    PMC * stash = $2;
  -    if (!$2)
  +    if (PMC_IS_NULL($2))
        internal_exception(1, "Tried to get from null namespace.");
  -    if (!$3)
  +    if (PMC_IS_NULL($3))
        internal_exception(1, "Tried to get null global.");
   
       next = expr NEXT();
  -    if (!VTABLE_exists_keyed_str(interpreter, stash, $3)) {
  -     if (PARROT_ERRORS_test(interpreter, PARROT_ERRORS_GLOBALS_FLAG))  {
  -         real_exception(interpreter, next, GLOBAL_NOT_FOUND,
  -                 "Global '%Ss' not found\n", $3);
  -     }
  -     else {
  -         $1 = pmc_new(interpreter, enum_class_Undef);
  -     }
  -    }
  -    else {
  -     $1 = VTABLE_get_pmc_keyed_str(interpreter, stash, $3);
  -    }
  +    $1 = Parrot_get_global_p(interpreter, $2, $3);
       goto NEXT();
   }
   
  
  
  
  1.16      +112 -7    parrot/src/global.c
  
  Index: global.c
  ===================================================================
  RCS file: /cvs/public/parrot/src/global.c,v
  retrieving revision 1.15
  retrieving revision 1.16
  diff -u -r1.15 -r1.16
  --- global.c  30 Mar 2005 09:07:29 -0000      1.15
  +++ global.c  30 Mar 2005 11:12:35 -0000      1.16
  @@ -1,6 +1,6 @@
   /*
   Copyright: 2004 The Perl Foundation.  All Rights Reserved.
  -$Id: global.c,v 1.15 2005/03/30 09:07:29 leo Exp $
  +$Id: global.c,v 1.16 2005/03/30 11:12:35 leo Exp $
   
   =head1 NAME
   
  @@ -113,6 +113,43 @@
   }
   
   PMC *
  +Parrot_find_global_p(Parrot_Interp interpreter, PMC *ns, STRING *name)
  +{
  +    PMC *stash;
  +    STRING *class, *ns_name;
  +
  +    if (PMC_IS_NULL(ns))
  +        return Parrot_find_global(interpreter, NULL, name);
  +    switch (ns->vtable->base_type) {
  +        case enum_class_String:
  +            return Parrot_find_global(interpreter, PMC_str_val(ns), name);
  +        case enum_class_Key:
  +            stash = interpreter->globals->stash_hash;
  +            while (1) {
  +                class = key_string(interpreter, ns);
  +                ns_name = string_concat(interpreter,
  +                        string_from_cstring(interpreter, "\0", 1),
  +                        class, 0);
  +                if (!VTABLE_exists_keyed_str(interpreter, stash, ns_name)) {
  +                    return NULL;
  +                }
  +                stash = VTABLE_get_pmc_keyed_str(interpreter, stash, 
ns_name);
  +                ns = key_next(interpreter, ns);
  +                if (!ns)
  +                    break;
  +            }
  +            assert(ns->vtable->base_type == enum_class_Hash);
  +            /* fall through */
  +        case enum_class_Hash:
  +            if (!VTABLE_exists_keyed_str(interpreter, ns, name)) {
  +                return NULL;
  +            }
  +            return VTABLE_get_pmc_keyed_str(interpreter, ns, name);
  +    }
  +    return NULL;
  +}
  +
  +PMC *
   Parrot_get_global(Parrot_Interp interpreter, STRING *class,
           STRING *name, void *next)
   {
  @@ -126,7 +163,22 @@
                   "Global '%Ss' not found",
                   name);
       }
  +    return pmc_new(interpreter, enum_class_Undef);
  +}
   
  +PMC *
  +Parrot_get_global_p(Parrot_Interp interpreter, PMC *ns, STRING *name)
  +{
  +    PMC *g = Parrot_find_global_p(interpreter, ns, name);
  +    if (g)
  +        return g;
  +    if (PARROT_ERRORS_test(interpreter, PARROT_ERRORS_GLOBALS_FLAG))  {
  +        real_exception(interpreter, NULL, E_NameError,
  +               Interp_flags_TEST(interpreter, PARROT_PYTHON_MODE) ?
  +                "global name '%Ss' is not defined" :
  +                "Global '%Ss' not found",
  +                name);
  +    }
       return pmc_new(interpreter, enum_class_Undef);
   }
   
  @@ -242,16 +294,13 @@
       Parrot_invalidate_method_cache(interpreter, class);
   }
   
  -void
  -Parrot_store_sub_in_namespace(Parrot_Interp interpreter, PMC* sub_pmc)
  +static void
  +store_sub_in_namespace(Parrot_Interp interpreter, PMC* sub_pmc,
  +        PMC *name_space, STRING *sub_name)
   {
       PMC *globals = interpreter->globals->stash_hash;
       INTVAL type, class_type;
  -    STRING* sub_name;
  -    PMC *name_space;
   
  -    sub_name = PMC_sub(sub_pmc)->name;
  -    name_space = PMC_sub(sub_pmc)->name_space;
   #if DEBUG_GLOBAL
       fprintf(stderr, "PMC_CONST: store_global: name '%s' ns %s\n",
               (char*)sub_name->strstart,
  @@ -315,6 +364,62 @@
       }
   }
   
  +/* XXX in mmd.c ? */
  +STRING* Parrot_multi_long_name(Parrot_Interp interpreter, PMC* sub_pmc);
  +
  +STRING*
  +Parrot_multi_long_name(Parrot_Interp interpreter, PMC* sub_pmc)
  +{
  +    PMC *multi_sig;
  +    STRING* sub_name, *sig;
  +    INTVAL i, n;
  +
  +    sub_name = PMC_sub(sub_pmc)->name;
  +    multi_sig = PMC_sub(sub_pmc)->multi_signature;
  +    n = VTABLE_elements(interpreter, multi_sig);
  +    /*
  +     * foo @MULTI(STRING, Integer) =>
  +     *
  +     * [EMAIL PROTECTED]@Integer
  +     */
  +    for (i = 0; i < n; ++i) {
  +        sig = VTABLE_get_string_keyed_int(interpreter, multi_sig, i);
  +        sub_name = string_concat(interpreter, sub_name,
  +                const_string(interpreter, "_@"), 0);
  +        sub_name = string_concat(interpreter, sub_name, sig, 0);
  +    }
  +    return sub_name;
  +}
  +
  +void
  +Parrot_store_sub_in_namespace(Parrot_Interp interpreter, PMC* sub_pmc)
  +{
  +    STRING* sub_name;
  +    PMC *multi_sig;
  +    PMC *name_space;
  +
  +    sub_name = PMC_sub(sub_pmc)->name;
  +    name_space = PMC_sub(sub_pmc)->name_space;
  +    multi_sig = PMC_sub(sub_pmc)->multi_signature;
  +    if (PMC_IS_NULL(multi_sig)) {
  +        store_sub_in_namespace(interpreter, sub_pmc, name_space, sub_name);
  +    }
  +    else {
  +        STRING *long_name;
  +        PMC *multi_sub;
  +
  +        multi_sub = Parrot_find_global_p(interpreter, name_space, sub_name);
  +        if (!multi_sub) {
  +            multi_sub = pmc_new(interpreter, enum_class_MultiSub);
  +            store_sub_in_namespace(interpreter, multi_sub,
  +                    name_space, sub_name);
  +        }
  +        VTABLE_push_pmc(interpreter, multi_sub, sub_pmc);
  +        long_name = Parrot_multi_long_name(interpreter, sub_pmc);
  +        store_sub_in_namespace(interpreter, sub_pmc, name_space, long_name);
  +    }
  +}
  +
   /*
   
   =back
  
  
  
  1.55      +33 -9     parrot/src/mmd.c
  
  Index: mmd.c
  ===================================================================
  RCS file: /cvs/public/parrot/src/mmd.c,v
  retrieving revision 1.54
  retrieving revision 1.55
  diff -u -r1.54 -r1.55
  --- mmd.c     24 Mar 2005 14:08:19 -0000      1.54
  +++ mmd.c     30 Mar 2005 11:12:35 -0000      1.55
  @@ -1,6 +1,6 @@
   /*
   Copyright: 2003 The Perl Foundation.  All Rights Reserved.
  -$Id: mmd.c,v 1.54 2005/03/24 14:08:19 leo Exp $
  +$Id: mmd.c,v 1.55 2005/03/30 11:12:35 leo Exp $
   
   =head1 NAME
   
  @@ -862,7 +862,7 @@
        *    if the first found function is a plain Sub: finito
        */
       n = VTABLE_elements(interpreter, candidate_list);
  -    if (n) {
  +    if (n == 1) {
           pmc = VTABLE_get_pmc_keyed_int(interpreter, candidate_list, 0);
           _sub = CONST_STRING(interpreter, "Sub");
   
  @@ -871,7 +871,7 @@
           }
       }
       /*
  -     * 4) first is a MultiSub - go through all found MultiSubs and check
  +     * 4) first was a MultiSub - go through all found MultiSubs and check
        *    the first arguments MRO, add all MultiSubs and plain methods,
        *    where the first argument matches
        */
  @@ -914,6 +914,7 @@
        */
       type1 = VTABLE_get_integer_keyed_int(interpreter, arg_tuple, 0);
       if (type1 < 0) {
  +        return;
           internal_exception(1, "unimplemted native MMD type");
           /* TODO create some class namespace */
       }
  @@ -942,7 +943,7 @@
   {
       short da = a & 0xffff;
       short db = b & 0xffff;
  -    return da > db ? -1 : da < db ? 1 : 0;
  +    return da > db ? 1 : da < db ? -1 : 0;
   }
   
   extern void Parrot_FixedPMCArray_sort(Interp* , PMC* pmc, PMC *cmp_func);
  @@ -958,13 +959,33 @@
   
   */
   
  +#define MMD_BIG_DISTANCE 0x7fff
  +
   static UINTVAL
   mmd_distance(Interp *interpreter, PMC *pmc, PMC *arg_tuple)
   {
  +    PMC *multi_sig;
  +    INTVAL n, args, dist;
  +
  +    multi_sig = PMC_sub(pmc)->multi_signature;
  +    if (!multi_sig) {
  +        /* some method */
  +        return 0;
  +    }
  +    n = VTABLE_elements(interpreter, multi_sig);
  +    args = VTABLE_elements(interpreter, arg_tuple);
       /*
  -     * TODO need a signaute in the sub pmc
  +     * arg_tuple may have more arguments - only the
  +     * n multi_sig invocants are counted
        */
  -    return 0;
  +    if (args < n)
  +        return MMD_BIG_DISTANCE;
  +    dist = 0;
  +    if (args > n)
  +        dist = 1;
  +    /*
  +     * TODO run through arg types */
  +    return dist;
   }
   
   /*
  @@ -980,7 +1001,7 @@
   static void
   mmd_sort_candidates(Interp *interpreter, PMC *arg_tuple, PMC *cl)
   {
  -    INTVAL i, n, d;
  +    INTVAL i, n, d, i3;
       PMC *nci, *pmc, *sort;
       INTVAL *helper;
       PMC **data;
  @@ -997,7 +1018,7 @@
       for (i = 0; i < n; ++i) {
           pmc = VTABLE_get_pmc_keyed_int(interpreter, cl, i);
           d = mmd_distance(interpreter, pmc, arg_tuple);
  -        helper[i] = i << 16 | d;
  +        helper[i] = i << 16 | (d & 0xffff);
       }
       /*
        * need an NCI function pointer
  @@ -1007,7 +1028,10 @@
       /*
        * sort it
        */
  +    i3 = REG_INT(3);
  +    REG_INT(3) = 1;
       Parrot_FixedPMCArray_sort(interpreter, sort, nci);
  +    REG_INT(3) = i3;
       /*
        * now helper has a sorted list of indices in the upper 16 bits
        * fill helper with sorted candidates
  @@ -1099,7 +1123,7 @@
       INTVAL i, n;
   
       _sub = CONST_STRING(interpreter, "Sub");
  -    _multi_sub = CONST_STRING(interpreter, "Multi_Sub");
  +    _multi_sub = CONST_STRING(interpreter, "MultiSub");
   
       if (VTABLE_isa(interpreter, pmc, _sub)) {
           /* a plain sub stops outer searches */
  
  
  
  1.16      +31 -2     parrot/t/pmc/mmd.t
  
  Index: mmd.t
  ===================================================================
  RCS file: /cvs/public/parrot/t/pmc/mmd.t,v
  retrieving revision 1.15
  retrieving revision 1.16
  diff -u -r1.15 -r1.16
  --- mmd.t     24 Mar 2005 14:08:20 -0000      1.15
  +++ mmd.t     30 Mar 2005 11:12:36 -0000      1.16
  @@ -1,6 +1,6 @@
   #! perl -w
   # Copyright: 2001-2003 The Perl Foundation.  All Rights Reserved.
  -# $Id: mmd.t,v 1.15 2005/03/24 14:08:20 leo Exp $
  +# $Id: mmd.t,v 1.16 2005/03/30 11:12:36 leo Exp $
   
   =head1 NAME
   
  @@ -16,7 +16,7 @@
   
   =cut
   
  -use Parrot::Test tests => 10;
  +use Parrot::Test tests => 11;
   
   pir_output_is(<<'CODE', <<'OUTPUT', "PASM divide");
   
  @@ -352,3 +352,32 @@
     Bar::foo
   OUT
   
  +pir_output_is(<<'CODE', <<'OUT', "MMD on argument count");
  +.namespace ["main"]
  +.sub main @MAIN
  +    p("ok 1\n")
  +    p("-twice", "ok 2\n")
  +.end
  +
  +.namespace [""]
  +
  +.sub p @MULTI(string)
  +    .param string s
  +    print s
  +.end
  +
  +.sub p @MULTI(string, string)
  +    .param string opt
  +    .param string s
  +    if opt != '-twice' goto no_twice
  +     print s
  +     print s
  +    .return()
  +no_twice:
  +    print s
  +.end
  +CODE
  +ok 1
  +ok 2
  +ok 2
  +OUT
  
  
  

Reply via email to