在Tcl' expr'中将参数视为字符串声明

时间:2014-12-31 13:23:08

标签: if-statement tcl expr

我使用的短语法如果'声明如下:

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的值,这仅仅是“价值”的科学记数。

但是,我需要'数据'成为'价值' (例如,写入外部寄存器)。

有什么想法吗?

1 个答案:

答案 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将结果组合成十六进制(如果需要)。像这样,它更容易考虑而不仅仅是表示