Posted to tcl by aspect at Wed Nov 23 23:05:31 GMT 2016view raw
- proc proc* {name arglist body} {
- set upargs [lsearch -inline -all $arglist _*]
- if {[llength $upargs]} {
- set upvar [list ::upvar 1]
- foreach a $upargs {
- append upvar " \$$a [list [string range $a 1 end]]"
- }
- set body "$upvar;$body"
- }
- tailcall ::proc $name $arglist $body
- }
- # clamp saves some tedium and getting max/min confused
- proc* clamp {_x min max} {
- if {$x < $min} {set x $min}
- if {$x > $max} {set x $max}
- return $x
- }
- # incrmod 10 i 3 -> 0 3 6 9 2 5 8 1 4 7 ..
- proc* incrmod {modulus _var {increment 1}} {
- set var [expr {($var + $increment) % $modulus}]
- }
- # assertions, if nothing else, are a nice default error message
- proc assert {x {msg ""}} {
- if {![uplevel 1 expr [list $x]]} {
- catch {
- set y [uplevel 1 [list subst -noc $x]]
- if {$y ne $x} {
- set x "{$y} from {$x}"
- }
- }
- throw ASSERT "[concat "Assertion failed!" $msg] $x"
- }
- }
- proc test {} {
- set a 12
- assert {[clamp a 0 10] == 10}
- assert {[clamp a 5 15] == 10}
- assert {[clamp a 12 20] == 12}
- assert {[incrmod 12 a 1] == 1}
- }
- test