问小白 wenxiaobai
资讯
历史
科技
环境与自然
成长
游戏
财经
文学与艺术
美食
健康
家居
文化
情感
汽车
三农
军事
旅行
运动
教育
生活
星座命理

TCL语法详解之foreach语句

创作时间:
作者:
@小白创作中心

TCL语法详解之foreach语句

引用
CSDN
1.
https://blog.csdn.net/inspirewang/article/details/139609612

上一篇我们介绍了如何使用TCL解析TCL中的if命令,这一篇我们来介绍如何使用TCL解析TCL中的foreach命令。

首先我们来回顾下foreach语句的语法:

foreachvar1list1?var2list2 ...?body

从语法定义中,我们可以得出一个结论:将foreach语句看做一个字符串列表时,列表的第一个元素(foreach)是foreach命令的关键字、最后一个元素(body)是foreach语句循环执行的语句块、其余元素是以键值对形式出现的可被遍历的数据(list1list2……)和用于遍历其数据的变量或者变量列表(var1 var2 ……)。其中变量和其对应的数据至少有一对(var1list1)。

TCL的foreach命令的执行逻辑是,var1中的变量每次在执行body定义的代码块前,会先从list1定义的列表中取值。如果var1中定义了多个变量(以列表的形式给出),那么每次都会依次在list1定义的列表中取出对应数量的元素,并赋值给这些变量,这个过程类似于执行了lassign命令,每次取出的值不会出现在foreach循环的下一次取值的操作中。取值过程如下图所示:

每一对键值对在foreach循环的每一次执行前都是如此取值,每次这些取到值的变量就可以在body定义的代码块执行时使用对应的值,那些没有能够取得值的变量在body定义的代码块执行时使用空值进行运算。foreach循环的次数取决于命令定义的键值对中能够取值次数最多的那一对。

下面我们给我我的的解析简易代码:

proc EvalForeachCmd {foreachcmd {clevel 1}} {
    set res ""
    set block3 [lindex $foreachcmd end]
    set argslist [lrange $foreachcmd 1 end-1]
    set breaksign 1
    while {$breaksign} {
        set templist {}
        foreach {block1 block2} $argslist {
            set block2 [uplevel $clevel [concat [list lassign $block2] $block1]]
            lappend templist $block1 $block2
        }
        set argslist $templist
        set res [uplevel $clevel "$block3"]
        set breaksign 0
        foreach {block1 block2} $argslist {
            if {$block2 ne ""} {
                set breaksign 1
            }
        }
    }
}  

上述代码实现了TCL中foreach命令解释执行的基本逻辑。

当然TCL中foreach命令完整解析还不仅仅这么简单,还需要考虑其内部的break命令、continue命令以及return命令等其他影响foreach命令执行过程的命令的影响。这里我们暂时不做详解,感兴趣的同学可以自行研究。

© 2023 北京元石科技有限公司 ◎ 京公网安备 11010802042949号