0

我正在使用这样的“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”语句始终将其参数视为整数,“数据”得到的值是 4e+20,这仅仅是“值”的科学记数法。

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

有任何想法吗?

4

1 回答 1

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的,只是给出值作为结果。“显而易见且可发现”……</p>

如果您仍在使用 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结果组合回十六进制(如有必要)。像这样,考虑value而不仅仅是表示会容易得多。

于 2014-12-31T22:30:38.587 回答