# New Ticket Created by Vasily Chekalkin # Please include the string: [perl #54514] # in the subject line of all future correspondence about this issue. # <URL: http://rt.perl.org/rt3/Ticket/Display.html?id=54514 >
Hello. There is initial implementation of sort for Lists. Only src/classes/List.pir affected. Example output: [EMAIL PROTECTED]:~/src/parrot/languages/perl6$ cat s2.t my @l = ('a', 'b', 'c', 'd', 1, 2, 3, 4); my @l1 = sort @l; say [EMAIL PROTECTED]; [EMAIL PROTECTED]:~/src/parrot/languages/perl6$ ../../parrot perl6.pbc s2.t 1 2 3 4 a b c d [EMAIL PROTECTED]:~/src/parrot/languages/perl6$ cat s3.t my @l = ('a', 'b', 'c', 'd', 1, 2, 3, 4); my @l1 = sort { $^b <=> $^a } , @l; say [EMAIL PROTECTED]; [EMAIL PROTECTED]:~/src/parrot/languages/perl6$ ../../parrot perl6.pbc s3.t 4 3 2 1 d c b a -- Bacek
Index: src/classes/List.pir =================================================================== --- src/classes/List.pir (revision 27652) +++ src/classes/List.pir (working copy) @@ -1018,6 +1036,148 @@ .return list.'uniq'() .end +=item $!merge + +Subsubroutine for merge-sort + +=cut + +.sub '$!merge' + .param pmc comparer + .param pmc left + .param pmc right + .local pmc result, l, r + .local int have_left, have_right + .local pmc closure + + result = new 'List' + $I0 = elements left + $I1 = elements right + + have_left = 0 + have_right = 0 + + loop_start: + + shift_left: + if have_left goto shift_right + unless left goto finish_right + l = shift left + have_left = 1 + + shift_right: + if have_right goto loop_body + unless right goto finish_left + + r = shift right + have_right = 1 + + loop_body: + closure = newclosure comparer + $I0 = closure(l, r) + if $I0 < 0 goto push_left + + push_right: + push result, r + have_right = 0 + goto loop_start + + push_left: + push result, l + have_left = 0 + goto loop_start + + + finish_left: + unless have_left goto finish_left_tail + push result, l + finish_left_tail: + unless left goto finish_right + l = shift left + push result, l + goto finish_left_tail + + finish_right: + unless have_right goto finish_right_tail + push result, r + finish_right_tail: + unless right goto finish + r = shift right + push result, r + goto finish_right_tail + + finish: + .return (result) + +.end + +=item $!merge_sort + +Implementation of merge-sort algorithm + +=cut + +.sub '$!merge_sort' + .param pmc comparer + .param pmc list + .local pmc left, right, result, elem + .local int len, half + + len = elements list + + unless len <= 1 goto lets_sort + .return (list) + + lets_sort: + left = new 'List' + right = new 'List' + half = len / 2 + + create_left: + if half < 1 goto create_right + elem = shift list + push left, elem + dec half + goto create_left + + create_right: + len = elements list + if len < 1 goto do_it + + elem = shift list + push right, elem + goto create_right + + do_it: + left = '$!merge_sort'(comparer, left) + right = '$!merge_sort'(comparer, right) + result = '$!merge'(left, right) + .return (result) +.end + + +.sub sort :multi(_, 'List') + .param pmc sorter + .param pmc list :slurpy + .local pmc sorted + + sorted = '$!merge_sort'(sorter, list :flat) + + .return (sorted) +.end + +.sub sort :multi('List') + .param pmc list :slurpy + .local pmc sorted + + get_global $P0, "infix:cmp" + sorted = '$!merge_sort'($P0, list :flat) + + $P0 = 'list'(sorted) + .return ($P0) +.end + + ## TODO: join map reduce sort zip =back