Permalink
Browse files

Implement &sort

  • Loading branch information...
sorear committed Oct 13, 2010
1 parent ea8058e commit 9f1bf0e2a9b0704112497f70af92c77a1a137e94
Showing with 53 additions and 10 deletions.
  1. +29 −8 lib/Kernel.cs
  2. +1 −0 src/CLRTypes.pm
  3. +1 −0 src/CgOp.pm
  4. +20 −0 test2.pl
  5. +2 −2 v6/TODO
View
@@ -890,6 +890,18 @@ public class Kernel {
return lv;
}
+ public static VarDeque SortHelper(Frame th, IP6 cb, VarDeque from) {
+ Variable[] tmp = from.CopyAsArray();
+ Array.Sort(tmp, delegate (Variable v1, Variable v2) {
+ Frame end = th.MakeChild(null, ExitRunloopSI);
+ Frame call = cb.Invoke(end, new Variable[] { v1, v2 }, null);
+ RunCore(call);
+ return (int)(double)UnboxAny(
+ ((Variable)end.resultSlot).Fetch());
+ });
+ return new VarDeque(tmp);
+ }
+
public static Variable ContextHelper(Frame th, string name) {
object rt;
while (th != null) {
@@ -1345,17 +1357,26 @@ public sealed class VarDeque {
return d;
}
+ private void CopyToArray(Variable[] tg) {
+ int z1 = data.Length - head;
+ if (z1 >= count) {
+ Array.Copy(data, head, tg, 0, count);
+ } else {
+ Array.Copy(data, head, tg, 0, z1);
+ int z2 = count - z1;
+ Array.Copy(data, 0, tg, z1, z2);
+ }
+ }
+
+ public Variable[] CopyAsArray() {
+ Variable[] ret = new Variable[count];
+ CopyToArray(ret);
+ return ret;
+ }
+
private void checkgrow() {
if (count == data.Length - 1) {
Variable[] ndata = new Variable[data.Length * 2];
- int z1 = data.Length - head;
- if (z1 >= count) {
- Array.Copy(data, head, ndata, 0, count);
- } else {
- Array.Copy(data, head, ndata, 0, z1);
- int z2 = count - z1;
- Array.Copy(data, 0, ndata, z1, z2);
- }
data = ndata;
head = 0;
}
View
@@ -131,6 +131,7 @@ my %typedata = (
'Kernel.DefaultNew' => [m => 'Variable'],
'Kernel.NewROScalar' => [m => 'Variable'],
'Kernel.NewRWScalar' => [m => 'Variable'],
+ 'Kernel.SortHelper' => [m => 'VarDeque'],
'Kernel.NewRWListVar' => [m => 'Variable'],
'Console.WriteLine' => [m => 'Void'],
'Console.Error.WriteLine' => [m => 'Void'],
View
@@ -193,6 +193,7 @@ use warnings;
sub vvarlist_unshiftn { rawcall($_[0], 'UnshiftN', $_[1]) }
sub vvarlist_push { rawcall($_[0], 'Push', $_[1]) }
sub vvarlist_item { getindex($_[0], $_[1]) }
+ sub vvarlist_sort { rawscall('Kernel.SortHelper', callframe(), $_[0], $_[1]) }
sub frame_caller { getfield('caller', $_[0]) }
sub frame_file { rawcall($_[0], 'ExecutingFile') }
View
@@ -1,5 +1,6 @@
# vim: ft=perl6
use Test;
+use MONKEY_TYPING;
sub infix:<x>($str, $ct) {
my $i = +$ct;
@@ -23,11 +24,30 @@ sub infix:<gt>($s1, $s2) { ($s1 leg $s2) > 0 }
sub infix:<le>($s1, $s2) { ($s1 leg $s2) <= 0 }
sub infix:<lt>($s1, $s2) { ($s1 leg $s2) < 0 }
+augment class Any {
+ method sort($cmp = &infix:<leg>) {
+ my $l = self.list.eager;
+ Q:CgOp {
+ (letn n (obj_newblank (obj_llhow (@ {List})))
+ (setslot flat (l n) (bool 1))
+ (setslot items (l n) (vvarlist_sort (@ {$cmp})
+ (getslot items vvarlist (@ {$l}))))
+ (setslot rest (l n) (vvarlist_new_empty))
+ (newrwlistvar (l n)))
+ }
+ }
+}
+
+sub sort(*@bits) { @bits.sort }
+
ok 'cow' le 'sow', 'cow le sow';
ok !('sow' le 'cow'), 'sow !le cow';
ok 'row' lt 'tow', 'row lt tow';
ok 'how' gt 'bow', 'how gt bow';
ok 'yow' ge 'yow', 'yow ge yow';
+is join("|", sort <c f d z a>), 'a|c|d|f|z', '&sort works';
+is join("|", <a3 b2 c1 d0>.sort({ substr($^a,1) leg substr($^b,1) })),
+ 'd0|c1|b2|a3', '.sort with callback works';
#is $?FILE, 'test.pl', '$?FILE works';
#is $?ORIG.substr(0,5), '# vim', '$?ORIG works';
View
@@ -1,9 +1,9 @@
~
<?{ }>
-<alpha>
() being Nil
circumfix:<[ ]>
Cursor.add_categorical
+Cursor.alpha
Cursor.canonicalize_name
Cursor.check_old_cclass
Cursor.cursor_all
@@ -28,7 +28,6 @@ $*FOO as a parameter
func(|($key => $value))
gt, lt, leg, etc
hash literals
-infix:<x>
List.at-pos(WhateverCode)
Match.CURSOR
Match.iterator should return numbered captures
@@ -50,6 +49,7 @@ defined($thing)
:exists
Hash.keys &keys
Hash.LISTSTORE
+infix:<x>
invert(%hash)
&item
&join

0 comments on commit 9f1bf0e

Please sign in to comment.