Version 0 of compute

Updated 2002-09-11 21:04:12

# compute provides some preprocessing capabilities for expr. # It will add a "$" sign to anything in the expression that # is a variable in the uplevel context, if it doesn't already # have one. It maps ' to " in the final translation, to insure # string comparisons are done in a string context, It maps # "and" to &&; "or" to ||; "not" to !; "<>" to !=; "true", "on" # and "yes" to 1 and "false", "off" and "no" to 0. It also # maps "pi" to 3.1415926535

proc compute { args } { # puts "expr $args"

  set exp ""
  set id ""
  regsub "''" [ string trim $args ] "@@@" args
  while 1 {
    regexp "(\[^a-zA-Z_'\]*)(\[a-zA-Z0-9_'\]*)(.*)" $args -> head id tail
    if ![ string length $id ] {
      set exp "$exp$head"
      break
    }
    set dollar ""
    if ![ string equal [ string index $id 0 ] "'" ] {
      if ![ string equal [info commands $id] "" ] {
        set id "\[ $id"
        regexp {[^\(]*\(([^\)]*)\)(.*)} $tail -> params tail
        set tail " $params \]$tail"
      } elseif [ uplevel info exists $id ] { set dollar "\$" }
    }
    append exp "$head$dollar$id"
    set args $tail
  }
  regsub -all "'" $exp "\"" exp
  set map "@@@ ' and && or || not ! <> != true 1 false 0 on 1 off 0 yes 1 no 0 pi 3.1415926535"
  foreach { from to } $map {
    regsub $from $exp $to exp
  }
  set exp [ uplevel subst \{$exp\} ]
  return [ expr $exp ]

}