[Richard Suchenwirth] 2004-01-13 - In [RPN in Tcl] I've played a bit with emulating [Forth] in Tcl. Here is a much shorter take that defines a single ''rpn'' proc, which takes a body in Reverse Polish Notation, and the rest of the arguments as the initial stack. The words in the body are executed from left to right, either as Forth-like stack operations, or as a Tcl command which has to have one argument (popped from stack) and whose result is pushed on the stack. ====== proc rpn {body args} { foreach word $body { switch -- $word { drop {pop args} dup {push args [lindex $args end]} swap {push args [pop args] [pop args]} + - "-" - * - / - % { #-- binary arithmetic operators: set 1 [pop args] push args [expr [pop args] $word $1] } default {push args [$word [pop args]]} } } set args } # Simple stack routines: interp alias {} push {} lappend proc pop stackName { upvar 1 $stackName stack K [lindex $stack end] [set stack [lrange $stack 0 end-1]] } # ..and the indispensable [K] combinator: proc K {a b} {set a} ====== This test will display the source file on stdout. Notice how no variables are needed at all (if you don't count the stack as the Big Variable : ====== puts [rpn {open dup read swap close drop} rpn.tcl] ====== What happens is the same as with ====== proc readfile fn { set fp [open $fn] set res [read $fp] close $fp return $res } ====== but the code feels quite different ;-) Schematic of how it works: (initial stack:) rpn.tcl open filexxx dup filexxx filexxx read filexxx (text) swap (text) filexxx close (text) "" drop (text) and the final stack, which in one element contains the file's contents, is returned to the caller. # Testing the newly added arithmetics, which cost the 4 LOC above: ====== puts [rpn {+ *} 4 2 1] ;# (2+1)*4 -> 12 ====== ---- ''Wow, Richard, what a delightful wizzlet! -[jcw]'' ---- A less minimal, but much more capable version is at [RPN again]. <> Arts and crafts of Tcl-Tk programming