Author: jonathan
Date: Thu Aug 14 07:08:33 2008
New Revision: 30229

Modified:
   trunk/languages/perl6/src/classes/Signature.pir
   trunk/languages/perl6/src/pmc/perl6multisub.pmc
   trunk/languages/perl6/t/pmc/perl6multisub-dispatch-arity.t

Log:
[rakudo] Collect type information from signatures in the MMD candidate sorter 
and and stub in building the DAG.

Modified: trunk/languages/perl6/src/classes/Signature.pir
==============================================================================
--- trunk/languages/perl6/src/classes/Signature.pir     (original)
+++ trunk/languages/perl6/src/classes/Signature.pir     Thu Aug 14 07:08:33 2008
@@ -19,8 +19,8 @@
 * type - the class or role type of the parameter; this references the actual
   type object rather than just naming it, and may well be parametric (but that
   will have been resolved already)
-* constraints - array of any additional "where" refinement types on the
-  parameter
+* constraints - any additional "where" refinement types on the parameter;
+  will be a junction of types
 * invocant - is this the invocant (as in, self for a method, not multi)
 * multi_invocant - is this an invocant for the purpose of MMD
 * optional - is this an optional parameter?
@@ -56,6 +56,17 @@
     .return ($P0)
 .end
 
+=item params
+
+Get the array of parameter describing hashes.
+
+=cut
+
+.sub 'params' :method
+    $P0 = getattribute self, "@!params"
+    .return ($P0)
+.end
+
 =back
 
 =cut

Modified: trunk/languages/perl6/src/pmc/perl6multisub.pmc
==============================================================================
--- trunk/languages/perl6/src/pmc/perl6multisub.pmc     (original)
+++ trunk/languages/perl6/src/pmc/perl6multisub.pmc     Thu Aug 14 07:08:33 2008
@@ -54,11 +54,12 @@
 
 
 typedef struct candidate_info {
-    PMC *sub;               /* The sub that is the candidate. */
-    INTVAL min_arity;       /* The number of required positonal arguments. */
-    INTVAL max_arity;       /* The number of required and optional positional 
arguments. */
-    PMC *type_cons;         /* Any class or role type constraints. */
-    PMC *refinement_cons;   /* Any refinement type constraints (C<subset>). */
+    PMC *sub;             /* The sub that is the candidate. */
+    INTVAL min_arity;     /* The number of required positonal arguments. */
+    INTVAL max_arity;     /* The number of required and optional positional 
arguments. */
+    PMC **types;          /* Class or role type constraints for each 
parameter. */
+    PMC **constraints;    /* Refinement type constraints for each parameter 
(if there
+                           * are many, this will be a junction). */
 } candidate_info;
 
 
@@ -74,6 +75,7 @@
 typedef struct candidate_graph_node {
     candidate_info *info;
     struct candidate_graph_node **edges;
+    int edges_count;
 } candidate_graph_node;
 
 
@@ -200,6 +202,21 @@
     return arg_list;
 }
 
+
+/*
+
+=item C<static INTVAL is_narrower(PARROT_INTERP, candidate_info *a, 
candidate_info *b)>
+
+Takes two candidates and determines if the first one is narrower than the
+second. Returns a true value if they are.
+
+*/
+static INTVAL is_narrower(PARROT_INTERP, candidate_info *a, candidate_info *b) 
{
+    /* XXX TODO */
+    return 0;
+}
+
+
 /*
 
 =item C<static candidate_info** sort_candidiates(PMC *candidates)>
@@ -209,7 +226,8 @@
 
 */
 static candidate_info** sort_candidiates(PARROT_INTERP, PMC *candidates) {
-    INTVAL i;
+    INTVAL i, j, sig_elems;
+    PMC *signature, *params, *meth;
 
     /* Allocate results array (just allocate it for worst case, which
      * is no ties ever, so a null between all of them, and then space
@@ -237,9 +255,39 @@
             info->max_arity = info->min_arity + VTABLE_get_integer(interp,
                     VTABLE_inspect_str(interp, candidate, CONST_STRING(interp, 
"pos_optional")));
 
-        /* Add it to graph node. */
-        graph[i] = mem_allocate_typed(candidate_graph_node);
+        /* Type information. */
+        meth = VTABLE_find_method(interp, candidate, CONST_STRING(interp, 
"signature"));
+        signature = Parrot_run_meth_fromc_args(interp, meth, candidate, 
CONST_STRING(interp, "signature"), "P");
+        meth = VTABLE_find_method(interp, signature, CONST_STRING(interp, 
"params"));
+        params = Parrot_run_meth_fromc_args(interp, meth, signature, 
CONST_STRING(interp, "params"), "P");
+        sig_elems = VTABLE_elements(interp, params);
+        info->types = mem_allocate_n_zeroed_typed(sig_elems + 1, PMC*);
+        info->constraints = mem_allocate_n_zeroed_typed(sig_elems + 1, PMC*);
+        for (j = 0; j < sig_elems; j++) {
+            PMC *param = VTABLE_get_pmc_keyed_int(interp, params, j);
+            PMC *type = VTABLE_get_pmc_keyed_str(interp, param, 
CONST_STRING(interp, "type"));
+            PMC *constraints = VTABLE_get_pmc_keyed_str(interp, param, 
CONST_STRING(interp, "constraints"));
+            info->types[j] = type;
+            info->constraints[j] = constraints;
+        }
+
+        /* Add it to graph node, and initialize list of edges. */
+        graph[i] = mem_allocate_zeroed_typed(candidate_graph_node);
         graph[i]->info = info;
+        graph[i]->edges = mem_allocate_n_zeroed_typed(num_candidates, 
candidate_graph_node*);
+    }
+
+    /* Now analyze type narrowness of the candidates relative to each other
+     * and create the edges. */
+    for (i = 0; i < num_candidates; i++) {
+        for (j = 0; j < num_candidates; j++) {
+            if (i == j)
+                continue;
+            if (is_narrower(interp, graph[i]->info, graph[j]->info)) {
+                graph[i]->edges[graph[i]->edges_count] = graph[j];
+                graph[i]->edges_count++;
+            }
+        }
     }
 
     /* XXX Here we do the topological sort. For now, just copy the values
@@ -412,6 +460,9 @@
     VTABLE opcode_t *invoke(void *next) {
         PMC *found;
 
+        /* Need to make sure current continuation doesn't get destroyed. */
+        PMC *saved_ccont = interp->current_cont;
+
         /* Make sure that we have a candidate list built. */
         candidate_info **candidates = NULL;
         PMC *unsorted;
@@ -430,11 +481,26 @@
                 VTABLE_elements(interp, unsorted), next);
 
         /* Invoke what was found. */
+        interp->current_cont = saved_ccont;
         return VTABLE_invoke(interp, found, next);
     }
 
 /*
 
+=item C<VTABLE void mark()>
+
+Marks the candidate list.
+
+*/
+    VTABLE void mark() {
+        PMC *candidates;
+        GETATTR_Perl6MultiSub_candidates(interp, SELF, candidates);
+        if (!PMC_IS_NULL(candidates))
+            pobject_lives(interp, (PObj*)candidates);
+    }
+
+/*
+
 =item VTABLE void push_pmc(PMC *sub)
 
 Adds a new candidate to the candidate list.

Modified: trunk/languages/perl6/t/pmc/perl6multisub-dispatch-arity.t
==============================================================================
--- trunk/languages/perl6/t/pmc/perl6multisub-dispatch-arity.t  (original)
+++ trunk/languages/perl6/t/pmc/perl6multisub-dispatch-arity.t  Thu Aug 14 
07:08:33 2008
@@ -34,10 +34,13 @@
 .sub 'simple'
     $P0 = new "Perl6MultiSub"
     $P1 = find_global 'simple_1'
+    'attach_any_sig'($P1, 0)
     push $P0, $P1
     $P1 = find_global 'simple_2'
+    'attach_any_sig'($P1, 1)
     push $P0, $P1
     $P1 = find_global 'simple_3'
+    'attach_any_sig'($P1, 3)
     push $P0, $P1
 
     $I0 = $P0()
@@ -72,8 +75,10 @@
 .sub 'with_optional'
     $P0 = new "Perl6MultiSub"
     $P1 = find_global 'with_optional_1'
+    'attach_any_sig'($P1, 0)
     push $P0, $P1
     $P1 = find_global 'with_optional_2'
+    'attach_any_sig'($P1, 2)
     push $P0, $P1
 
     $I0 = $P0()
@@ -96,6 +101,7 @@
 .sub 'with_slurpy'
     $P0 = new "Perl6MultiSub"
     $P1 = find_global 'with_slurpy_1'
+    'attach_any_sig'($P1, 0)
     push $P0, $P1
     
     $I0 = $P0()
@@ -114,8 +120,10 @@
 .sub 'another_with_slurpy'
     $P0 = new "Perl6MultiSub"
     $P1 = find_global 'another_with_slurpy_1'
+    'attach_any_sig'($P1, 0)
     push $P0, $P1
     $P1 = find_global 'another_with_slurpy_2'
+    'attach_any_sig'($P1, 1)
     push $P0, $P1
     
     $I0 = $P0()
@@ -135,6 +143,31 @@
 .end
 
 
+.sub 'attach_any_sig'
+    .param pmc sub
+    .param int num_params
+
+    # Get Any type.
+    .local pmc any
+    any = get_hll_global "Any"
+    
+    # Make signature.
+    $P0 = new 'Signature'
+    $P1 = new 'Perl6Array'
+    setattribute $P0, "@!params", $P1
+    $I0 = 0
+  param_loop:
+    if $I0 == num_params goto param_loop_end
+    $P2 = new 'Perl6Hash'
+    $P2["type"] = any
+    push $P1, $P2
+    inc $I0
+    goto param_loop
+  param_loop_end:
+
+    setprop sub, '$!signature', $P0
+.end
+
 # Local Variables:
 #   mode: pir
 #   fill-column: 100

Reply via email to