Author: azuroth
Date: Sat Oct 29 01:41:02 2005
New Revision: 9622

Added:
   trunk/languages/tcl/lib/commands/lsort.pir
   trunk/languages/tcl/t/cmd_lsort.t   (contents, props changed)
Modified:
   trunk/languages/tcl/t/cmd_for.t
Log:
Implemented some of tcl's lsort


Added: trunk/languages/tcl/lib/commands/lsort.pir
==============================================================================
--- (empty file)
+++ trunk/languages/tcl/lib/commands/lsort.pir  Sat Oct 29 01:41:02 2005
@@ -0,0 +1,195 @@
+#
+# [lsort]
+#
+
+.namespace [ "Tcl" ]
+
+.sub "&lsort"
+  .param pmc argv :slurpy
+
+  .local int return_type, argc
+  .local pmc retval
+  .local pmc compare
+  .local pmc sort
+
+  argc = argv
+  if argc == 0 goto wrong_args
+
+  compare = find_global "_Tcl\0builtins\0lsort", "ascii"
+  sort = find_global "_Tcl\0builtins\0lsort", "sort"
+
+  # possible options
+  .local int decr, unique
+chew_flag:
+  $P0 = shift argv
+  unless argv goto got_list
+
+  if $P0 == "-decreasing" goto c_decr
+  if $P0 == "-increasing" goto c_incr
+  if $P0 == "-unique" goto c_uniq
+  if $P0 == "-integer" goto c_int
+  # XXX dictionary, real, command etc necessary
+  branch bad_opt
+
+c_decr:
+  decr = 1
+  branch chew_flag
+c_incr:
+  decr = 0
+  branch chew_flag
+c_uniq:
+  unique = 1
+  branch chew_flag
+c_int:
+  compare = find_global "_Tcl\0builtins\0lsort", "integer"
+  branch chew_flag
+
+
+got_list:
+
+  unless decr goto skip_decr
+  $P0 = find_global "_Tcl\0builtins\0lsort", "reverse"
+  compare = $P0(compare)
+skip_decr:
+
+  .local pmc __list
+  __list = find_global "_Tcl", "__list"
+  $P0 = __list($P0)
+
+  sort(compare, $P0)
+
+  unless unique goto skip_unique
+  .local int c, size
+  size = $P0
+
+  if size == 0 goto strip_end
+  $P1 = $P0[0]
+strip_loop:
+  inc c
+  if c == size goto strip_end
+  $P2 = $P1
+  $P1 = $P0[c]
+
+  if $P1 != $P2 goto strip_loop
+  delete $P0[c]
+  dec c
+  dec size
+  branch strip_loop
+strip_end:
+
+skip_unique:
+  .return ($P0)
+
+bad_opt:
+  $S0 = "bad option \""
+  $S1 = $P0
+  $S0 .= $S1
+  $S0 .= "\": must be -ascii, -command, -decreasing, -dictionary, -increasing, 
-index, -integer, -real, or -unique"
+  .throw ($S0)
+wrong_args:
+  .throw ("wrong # args: should be \"lsort ?options? list\"")
+.end
+
+.namespace [ "_Tcl\0builtins\0lsort" ]
+
+.sub "sort"
+  .param pmc compare
+  .param pmc list
+
+  .local int size
+  size = list
+  size -= 1
+
+  quicksort(compare, list, 0, size)
+.end
+
+.sub "quicksort"
+  .param pmc compare
+  .param pmc list
+  .param int lo
+  .param int hi
+
+  if lo >= hi goto done
+
+  .local pmc pivot
+  pivot = list[hi]
+
+  .local int l,h
+  l = lo
+  h = hi
+
+move_loop:
+  inc_loop:
+    unless l < h goto inc_end
+    $P0 = list[l]
+    $I0 = compare($P0, pivot)
+    unless $I0 <= 0 goto inc_end
+    l += 1
+    branch inc_loop
+  inc_end:
+  dec_loop:
+    unless h > l goto dec_end
+    $P0 = list[h]
+    $I0 = compare($P0, pivot)
+    unless $I0 >= 0 goto dec_end
+    h -= 1
+    branch dec_loop
+  dec_end:
+
+  unless l < h goto move_end
+  $P0 = list[l]
+  $P1 = list[h]
+  list[l] = $P1
+  list[h] = $P0
+
+  branch move_loop
+move_end:
+
+  $P0 = list[l]
+  $P1 = list[hi]
+  list[l] = $P1
+  list[hi] = $P0
+
+  $I0 = l - 1
+  $I1 = l + 1
+  quicksort(compare, list, lo, $I0)
+  quicksort(compare, list, $I1, hi)
+
+done:
+  .return ()
+.end
+
+.sub "ascii"
+  .param pmc s1
+  .param pmc s2
+  $I0 = cmp_str s1, s2
+  .return ($I0)
+.end
+
+.sub "integer"
+  .param pmc s1
+  .param pmc s2
+# XXX check that they're actually integers
+  $I0 = cmp_num s1, s2
+  .return ($I0)
+.end
+
+.sub "reverse"
+  .param pmc compare
+  .local string code
+
+  print "-decreasing not implemented!"
+
+  code = <<"END_PIR"
+
+.sub "reversed" :anon
+  .param string s1
+  .param string s2
+  .return (0)
+.endsub
+
+END_PIR
+
+  $P0 = compreg "PIR"
+  .return $P0(code)
+.end

Modified: trunk/languages/tcl/t/cmd_for.t
==============================================================================
--- trunk/languages/tcl/t/cmd_for.t     (original)
+++ trunk/languages/tcl/t/cmd_for.t     Sat Oct 29 01:41:02 2005
@@ -16,3 +16,4 @@ TCL
 3
 4
 OUT
+

Added: trunk/languages/tcl/t/cmd_lsort.t
==============================================================================
--- (empty file)
+++ trunk/languages/tcl/t/cmd_lsort.t   Sat Oct 29 01:41:02 2005
@@ -0,0 +1,142 @@
+#!/usr/bin/perl
+
+use strict;
+use lib qw(tcl/t t . ../lib ../../lib ../../../lib);
+use Parrot::Test tests => 20;
+use Test::More;
+use vars qw($TODO);
+
+language_output_is("tcl",<<'TCL',<<OUT,"empty list");
+  puts [lsort {}]
+TCL
+
+OUT
+
+language_output_is("tcl",<<'TCL',<<OUT,"no args");
+  lsort
+TCL
+wrong # args: should be "lsort ?options? list"
+OUT
+
+language_output_is("tcl",<<'TCL',<<OUT,"bad option");
+  lsort blah {}
+TCL
+bad option "blah": must be -ascii, -command, -decreasing, -dictionary, 
-increasing, -index, -integer, -real, or -unique
+OUT
+
+language_output_is("tcl",<<'TCL',<<OUT,"one elem");
+  puts [lsort {SortMe}]
+TCL
+SortMe
+OUT
+
+language_output_is("tcl",<<'TCL',<<OUT,"implicit ASCII");
+  set a {a10 B2 b1 a1 a2}
+  puts [lsort $a]
+TCL
+B2 a1 a10 a2 b1
+OUT
+
+language_output_is("tcl",<<'TCL',<<OUT,"ASCII all same");
+  puts [lsort {z z z}]
+TCL
+z z z
+OUT
+
+language_output_is("tcl",<<'TCL',<<OUT,"few same");
+  puts [lsort {a z z t a monkey}]
+TCL
+a a monkey t z z
+OUT
+
+language_output_is("tcl",<<'TCL',<<OUT,"list of lists");
+  puts [lsort {{a b c} {} {a c d} {z z t}}]
+TCL
+{} {a b c} {a c d} {z z t}
+OUT
+
+language_output_is("tcl",<<'TCL',<<'OUT',"list of lists mixed");
+  puts [lsort {{3 2} {3 4} {} no way}]
+TCL
+{} {3 2} {3 4} no way
+OUT
+
+language_output_is("tcl",<<'TCL',<<'OUT',"list of lists mixed var subst");
+  set a {{3 2} {3 4} {} no way}
+  puts [lsort $a]
+TCL
+{} {3 2} {3 4} no way
+OUT
+
+language_output_is("tcl",<<'TCL',<<OUT,"explicit increasing");
+  set a {a10 B2 b1 a1 a2}
+  puts [lsort -increasing $a]
+TCL
+B2 a1 a10 a2 b1
+OUT
+
+language_output_is("tcl",<<'TCL',<<OUT,"unique");
+  set a {a10 B2 a2 B2 b1 a1 a2 z z t}
+  puts [lsort -unique $a]
+TCL
+B2 a1 a10 a2 b1 t z
+OUT
+
+language_output_is("tcl",<<'TCL',<<OUT,"unique empty");
+  set a {}
+  puts [lsort -unique $a]
+TCL
+
+OUT
+
+language_output_is("tcl",<<'TCL',<<OUT,"unique one elem");
+  set a {A}
+  puts [lsort -unique $a]
+TCL
+A
+OUT
+
+language_output_is("tcl",<<'TCL',<<OUT,"integer");
+  set a {10 2 30 5 0 -5 2}
+  puts [lsort -integer $a]
+TCL
+-5 0 2 2 5 10 30
+OUT
+
+language_output_is("tcl",<<'TCL',<<OUT,"integer unique");
+  set a {10 2 30 5 0 -5 2 -5}
+  puts [lsort -unique -integer $a]
+TCL
+-5 0 2 5 10 30
+OUT
+
+TODO: {
+  local $TODO = "no excuses!";
+
+language_output_is("tcl",<<'TCL',<<OUT,"integer die");
+  set a {10 10.2}
+  puts [lsort -integer $a]
+TCL
+expected integer but got "10.2"
+OUT
+
+language_output_is("tcl",<<'TCL',<<'OUT',"decreasing");
+  puts [lsort -decreasing {1 3 2 5 9 4 8 7 6}]
+TCL
+9 8 7 6 5 4 3 2 1
+OUT
+
+language_output_is("tcl",<<'TCL',<<OUT,"decreasing integer unique");
+  set a {10 2 30 5 0 -5 2}
+  puts [lsort -decreasing -integer -unique $a]
+TCL
+30 10 5 2 0 -5
+OUT
+
+language_output_is("tcl",<<'TCL',<<OUT,"dictionary");
+  set a {a10 B2 b1 a1 a2}
+  puts [lsort -dictionary $a]
+TCL
+a1 a2 a10 b1 B2
+OUT
+}

Reply via email to