Version 0 of In case of: select, another switch

Updated 2002-04-24 16:38:25

if 0 { I needed a switch command with variables in place of constants

       Here is the result.
       I added list of values in place of one value, and expression.
       I used case, CASE and default to name the needed internal procs.

       syntax is:
                  select value \
                  { 
                    case list_of_values script
                    ...  
                    ?default script?
                  }
               or 
                  select \
                  { 
                    case expr script
                    ... 
                    ?default script?
                  }
       default fires always so must be last (no check).
       As an added benefice you can put comments (or other commands)

       ulis
      }

 # the select proc

 proc select {args} \
 { 
  proc default {body} { uplevel 1 $body }
  set expr 0
  switch [llength $args] \
  {
    1       \
    { # case expr
      proc case {expr body} \
      { 
        if {[uplevel 1 expr $expr]} \
        { uplevel 1 $body; return -code return }
      }
      uplevel 1 [lindex $args 0]
    }
    2       \
    { # case list
      proc CASE {value list body} \
      { 
        if {[lsearch $list $value] != -1} \
        { uplevel 1 $body; return -code return }
      }
      set value [lindex $args 0]
      set body  [lindex $args 1]
      interp alias {} case {} CASE $value
      uplevel 1 $body
    }
    default \
    { error "syntax is select ?value? body" }
  }
  rename CASE ""
  interp alias {} case {}
  rename default ""
 }

 # some test cases

 set value key4
 foreach i {1 2 3} { set key$i key$i }
 select $value \
 {
  puts "value $value"
  # test for keys
  case key0               { puts "found key0" }
  case $key1              { puts "found $key1" }
  case [list $key2 $key3] { puts "found $key2 or $key3" }
  case {key4 key5}        { puts "found key4 or key5" }
  # default case
  default                 { puts "$value is not a valid key" }
 }

 set value 0
 select \
 {
  puts "value $value"
  case {$value <  0} { puts "negative value" }
  case {$value >  0} { puts "positive value" }
  case {$value == 0} { puts "null value" }
 }