perl.cvs.parrot
[Top] [All Lists]

[svn:parrot] r33835 - trunk/languages/perl6/src/builtins

Subject: [svn:parrot] r33835 - trunk/languages/perl6/src/builtins
From:
Date: Fri, 12 Dec 2008 08:12:30 -0800 PST
Newsgroups: perl.cvs.parrot

Author: pmichaud
Date: Fri Dec 12 08:12:30 2008
New Revision: 33835

Modified:
   trunk/languages/perl6/src/builtins/any-list.pir

Log:
[rakudo]:  Add by-value sort for e.g.,     %hash.sort { .value }


Modified: trunk/languages/perl6/src/builtins/any-list.pir
==============================================================================
--- trunk/languages/perl6/src/builtins/any-list.pir     (original)
+++ trunk/languages/perl6/src/builtins/any-list.pir     Fri Dec 12 08:12:30 2008
@@ -311,28 +311,64 @@
     by = get_hll_global 'infix:cmp'
   have_by:
 
+    ##  prepare self and FPA for sorting
     .local pmc list, fpa
     .local int elems
-
     list = self.'list'()
-    list.'!flatten'()
     elems = list.'elems'()
     fpa = new 'FixedPMCArray'
-    fpa = elems
-
-    .local int i
-    i = 0
+    assign fpa, elems
+    $I0 = by.'arity'()
+    if $I0 < 2 goto by_value_cmp
+
+    ##  normal compare function, build fpa from list
+    .local pmc it
+    elems = 0
+    it = iter list
   fpa_loop:
-    unless i < elems goto fpa_end
-    $P0 = list[i]
-    fpa[i] = $P0
-    inc i
+    unless it goto fpa_done
+    $P0 = shift it
+    fpa[elems] = $P0
+    inc elems
     goto fpa_loop
-  fpa_end:
+  fpa_done:
     fpa.'sort'(by)
     .tailcall 'list'(fpa)
+
+  by_value_cmp:
+    ##  Algorithm as Perl 6:
+    ##      my @v     = @list.map($by);
+    ##      my @slice = (0..^@list).sort: { @v[$^a] cmp @v[$^b]};
+    ##      return @list[ @slice ];
+
+    .local pmc values
+    values = list.'map'(by)
+    set_global '@!sort_values', values
+    ##  fill fpa with values 0..elems-1
+    $I0 = 0
+  fpa_range_loop:
+    unless $I0 < elems goto fpa_range_done
+    fpa[$I0] = $I0
+    inc $I0
+    goto fpa_range_loop
+  fpa_range_done:
+    .const 'Sub' sbv = '!sort_by_value'
+    fpa.'sort'(sbv)
+    ##  return sorted slice of original list
+    .tailcall list.'postcircumfix:[ ]'(fpa)
 .end
 
+.sub '!sort_by_value' :anon
+    .param pmc a
+    .param pmc b
+    .local pmc values
+    values = get_global '@!sort_values'
+    $P0 = values[a]
+    $P1 = values[b]
+    $I0 = 'infix:cmp'($P0, $P1)
+    .return ($I0)
+.end
+    
 =back
 
 =cut

<Prev in Thread] Current Thread [Next in Thread>
  • [svn:parrot] r33835 - trunk/languages/perl6/src/builtins, pmichaud <=