我使用的短语法如果'声明如下:
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'声明总是把它的论点视为整数,'数据'获得4e + 20的值,这仅仅是“价值”的科学记数。
但是,我需要'数据'成为'价值' (例如,写入外部寄存器)。
有什么想法吗?
答案 0 :(得分:1)
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
将结果组合成十六进制(如果需要)。像这样,它更容易考虑值而不仅仅是表示。