在tcl中实现自定义if过程

问题描述 投票:0回答:1

我正在尝试在 tcl 中实现一个自定义的 if 过程,我们称之为 if+。对于初学者来说,我希望 if+ 能够准确地执行 if 正在执行的操作。

到目前为止我所拥有的:

proc if+ {expr1 body1 args} {
    if {[uplevel 1 [list expr $expr1]]} {
        uplevel 1 $body1
        return
    }
    for {set i 0} {$i < [llength $args]} {incr i 3} {
        if {[lindex $args $i] eq "else"} {
            uplevel 1 [lindex $args [expr $i+1]]
            return
        } elseif {[lindex $args $i] eq "elseif"} {
            if {[uplevel 1 [list expr [lindex $args [expr $i+1]]]]} {
                uplevel 1 [lindex $args [expr $i+2]]
                return
            }
        }
    }
}

它已经工作得很好,但有一个例外:当您将 return 语句放入一个 if+ 块的主体中时,它仅从 if+ 返回,而不是从其周围的过程返回。这可以从这个简单的例子中看出:

proc p {} {
    if+ true {
        puts A
        return
    }
    puts B
}

这个过程的输出是'A'和'B',而使用if而不是if+,它只是'A'。如何修改我的 if+ 使其与 if 完全相同?

if-statement tcl
1个回答
0
投票

您可以使用

try
捕获
return
并将 1 添加到其 level,以便它从调用堆栈中的正确函数返回:

proc if+ {expr1 body1 args} {
    try {
        if {[uplevel 1 [list expr $expr1]]} {
            uplevel 1 $body1
            break ;# instead of return
        }
        for {set i 0} {$i < [llength $args]} {incr i 3} {
            if {[lindex $args $i] eq "else"} {
                uplevel 1 [lindex $args $i+1]
                break
            } elseif {[lindex $args $i] eq "elseif"} {
                if {[uplevel 1 [list expr [lindex $args $i+1]]]} {
                    uplevel 1 [lindex $args $i+2]
                    break
                }
            }
        }
    } on return {val options} {
        dict incr options -level
        return -options $options $val
    }
}

另请注意删除了

expr
参数中的
lindex
调用;在这种情况下不需要它们,因为
lindex
本身可以进行数学计算,但如果您确实使用
expr
来做这样的事情,支撑您的
expr
-essions

© www.soinside.com 2019 - 2024. All rights reserved.