Sarnold 2005-11-10 -- The purpose is to offer a simple let command that works very much like C assignements for basic computations. The goal is not to join the general thing, but rather to keep it simple for everyday work.
Here is how it works :
% let a = 10 10 % let a = $a - 1 9 % puts $a 9 % let a *= 2 18
Please note that arguments have to be distinct. You cannot write this:
let a = $a+2
or this:
let a= 3 * 4
Warning: You may encounter problems with precision on floating-point values. It is not designed for precision, as the following example shows:
% let a = 1.0 / 3 0.333333333333 % let a *= 3 0.999999999999 % set x [expr {1.0/3}] 0.333333333333 % set x [expr {$x*3}] 1.0
Here it is :
proc let {varname assign args} { upvar $varname leftvalue if {[llength $args]==3} { # args look like : 1 + 3, $a - $b, $c / $d foreach {a op b} $args {break} set args [expr [string map [list a $a op $op b $b] {a op b}]] } if {[llength $args]==1} { switch -exact -- $assign { += {set leftvalue [expr {$leftvalue+$args}]} -= {set leftvalue [expr {$leftvalue-$args}]} *= {set leftvalue [expr {$leftvalue*$args}]} /= {set leftvalue [expr {$leftvalue/$args}]} %= {set leftvalue [expr {$leftvalue%$args}]} = {set leftvalue $args} default {error "invalid syntax : second argument is not an assignment"} } return $leftvalue } if {[llength $args]==0} { error "invalid argument number, check you have not put arguments and operators together" } error "syntax error" }