References to multis (at PIR level)

Moritz Lenz moritz at casella.verplant.org
Tue Sep 23 19:02:14 UTC 2008


For Rakudo I tried to implement infix:<cmp>(Pair $a, Pair $b) today, and
ran into some issues.

The initial implementation seems simple:

Index: src/classes/Pair.pir
===================================================================
--- src/classes/Pair.pir        (revision 31367)
+++ src/classes/Pair.pir        (working copy)
@@ -93,6 +93,19 @@
     .return $P0.'new'('key'=>key, 'value'=>value)
 .end

+.sub 'infix:cmp' :multi('Perl6Pair', 'Perl6Pair')
+    .param pmc lhs
+    .param pmc rhs
+    $P0 = lhs.'key'()
+    $P1 = rhs.'key'()
+    $I0 = 'infix:cmp'($P0, $P1)
+   if $I0 goto done
+    $P0 = lhs.'value'()
+    $P0 = lhs.'value'()
+    $I0 = 'infix:cmp'($P0, $P1)
+   done:
+    .return($I0)
+.end

 =back

That sub is never called, because in src/builtins/cmp.pir there's a
.sub 'infix:cmp'
without a :multi. Adding a :multi to it:
Index: src/builtins/cmp.pir
===================================================================
--- src/builtins/cmp.pir        (revision 31367)
+++ src/builtins/cmp.pir        (working copy)
@@ -140,7 +140,7 @@
 .end


-.sub 'infix:cmp'
+.sub 'infix:cmp' :multi(_,_)
     .param pmc a
     .param pmc b
     $I0 = cmp a, b

makes the multi dispatch choose the correct one, but it it breaks sort:

$ ../../parrot perl6.pbc -e '(1,2).sort'
No applicable methods.

current instr.: 'parrot;Any;sort' pc 3090 (src/gen_builtins.pir:2129)
called from Sub 'parrot;Any;sort' pc 10473 (src/gen_builtins.pir:6566)
[...]

The corresponding code (src/builtins/any-list.pir) is this:

.namespace ['Any']
.sub 'sort' :method :multi(_)
    .param pmc by              :optional
    .param int has_by          :opt_flag
    if has_by goto have_by
    by = get_hll_global 'infix:cmp'
  have_by:

    .local pmc list, fpa

[...]

    fpa.'sort'(by)
    .return 'list'(fpa)
.end

So my guess is that "by = get_hll_global 'infix:cmp'" fails, because
there's no single sub with that name anymore.

Is there a construct that lets me find a multi, and that will later do
dispatch based on the types of the parameters that I'll hand to it?

Moritz

-- 
Moritz Lenz
http://moritz.faui2k3.org/ |  http://perl-6.de/


More information about the parrot-dev mailing list