proc + {a b} {return [expr {$a + $b}]}
proc - {a b} {return [expr {$a - $b}]}
proc * {a b} {return [expr {$a * $b}]}
proc / {a b} {return [expr {$a / $b}]}

set stack [list]
while {1} {
    set line [gets stdin]
    foreach x [split $line " "] {
        # Use introspection to see if we've been given the name
        # of a procedure and, if so, find out how many args it 
        # wants, then pop them and evaluate it.
        if {[info proc $x] != ""} {
            set num_args [llength [info args $x]]
            if {[llength $stack] < $num_args} {
                error "Not enough operands on stack for $x"
            }
            set op_args [lrange $stack end-[expr {$num_args-1}] end]
            set stack [concat \
                [lrange $stack 0 end-$num_args]\
                [eval [list $x] $op_args]]
        } else {
            lappend stack $x
        }
    }
    puts [lindex $stack end]
}

