将参数视为 Tcl 'expr'语句中的字符串



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

相关内容

  • 没有找到相关文章

最新更新