RosettaCodeData/Task/Parsing-RPN-calculator-algo.../Tcl/parsing-rpn-calculator-algo...

50 lines
1000 B
Tcl

# Helper
proc pop stk {
upvar 1 $stk s
set val [lindex $s end]
set s [lreplace $s end end]
return $val
}
proc evaluate rpn {
set stack {}
foreach token $rpn {
set act "apply"
switch $token {
"^" {
# Non-commutative operation
set a [pop stack]
lappend stack [expr {[pop stack] ** $a}]
}
"/" {
# Non-commutative, special float handling
set a [pop stack]
set b [expr {[pop stack] / double($a)}]
if {$b == round($b)} {set b [expr {round($b)}]}
lappend stack $b
}
"*" {
# Commutative operation
lappend stack [expr {[pop stack] * [pop stack]}]
}
"-" {
# Non-commutative operation
set a [pop stack]
lappend stack [expr {[pop stack] - $a}]
}
"+" {
# Commutative operation
lappend stack [expr {[pop stack] + [pop stack]}]
}
default {
set act "push"
lappend stack $token
}
}
puts "$token\t$act\t$stack"
}
return [lindex $stack end]
}
puts [evaluate {3 4 2 * 1 5 - 2 3 ^ ^ / +}]