我正在使用"if"语句的简短语法,如下所示:
proc WriteParameter {Parameter Value} {
# Ugly option - WORKS
if {$Parameter eq "Unique"} {
set Register ControlStatus
set Data ${Value}0
set Mask EF
} else {
set Register $Parameter
set Data $Value
set Mask {}
}
# Elegant option - DOESN'T WORK
set Register [expr {$Parameter eq "Unique" ? "ControlStatus" : $Parameter}]
set Data [expr {$Parameter eq "Unique" ? ${Value}0 : $Value}]
set Mask [expr {$Parameter eq "Unique" ? EF : {}}]
puts $Register-$Data-$Mask
return 0
}
set Value 4E20 ;# Merely hexadecimal number
set Parameter Regular
WriteParameter $Parameter $Value
问题在于,在优雅的选项中,由于"expr"语句始终将其参数视为整数,因此"Data"获得的值为4e+20,这仅仅是"Value"的科学记数法。
但是,我需要"数据"是"值"(例如,写入外部寄存器)。
有什么想法吗?
expr
语言与Tcl的其他语言有很大不同。你必须更关心那里的语法。将内容放在"
双引号中会有所帮助"
。
set Register [expr {$Parameter eq "Unique" ? "ControlStatus" : $Parameter}]
set Data [expr {$Parameter eq "Unique" ? "${Value}0" : $Value}]
set Mask [expr {$Parameter eq "Unique" ? "EF" : {}}]
但是,您可能最好使用 if
,因为它不会尝试将其臂的结果转换为数字(大约使用 C 常量的规则),这与 expr
不同。
set Register [if {$Parameter eq "Unique"} {string cat ControlStatus} {string cat $Parameter}]
set Data [if {$Parameter eq "Unique"} {string cat $Value 0} {string cat $Value}]
set Mask [if {$Parameter eq "Unique"} {string cat EF}]
# We can omit the else clause; the default is an empty string anyway
这取决于 string cat
,这是在 Tcl 8.6.3 中引入的(嗯,8.6.2,但它的 I/O 子系统中有一些你真正想要避免的错误)。如果您使用的是从 8.5 到 8.6.1 的任何内容,请改用以下内容:
set Register [if {$Parameter eq "Unique"} {return -level 0 ControlStatus} {return -level 0 $Parameter}]
set Data [if {$Parameter eq "Unique"} {return -level 0 ${Value}0} {return -level 0 $Value}]
set Mask [if {$Parameter eq "Unique"} {return -level 0 EF}]
是的,return -level 0
只是给出结果的值。"显而易见且可发现"...
如果您使用的是 8.4 或更早版本(升级,伙计!您没有安全支持!然后你需要一个小的帮助程序:
proc value {value} {return $value}
set Register [if {$Parameter eq "Unique"} {value ControlStatus} {value $Parameter}]
set Data [if {$Parameter eq "Unique"} {value $Value 0} {value $Value}]
set Mask [if {$Parameter eq "Unique"} {value EF}]
上面的value
过程也适用于更高版本的 Tcl,但它提供的字节码效率较低。
但是,对于上述所有内容,我实际上会做一些不同的事情:
set Register $Parameter
set Data $Value
set Mask ""
if {$Parameter eq "Unique"} {
set Register ControlStatus
append Data 0
set Mask EF
}
我还可以使用 scan
来解析值,format
将结果组合回十六进制(如有必要)。像这样,考虑价值而不仅仅是表示会容易得多。