TCL是否有像LISP这样的宏

时间:2018-05-31 11:00:31

标签: tcl scala-macros

在LISP中,可以定义一个宏,它在相同的堆栈级别扩展,而不是添加到堆栈。在TCL中,可以调用一个过程,然后使用uplevel 1。我已经看到它在某些情况下会导致显着的减速。我想要的是宏观扩张。这在TCL有售吗?我找不到任何暗示它的确如此。

1 个答案:

答案 0 :(得分:1)

由于upvartailcalluplevel提供了一套相当不错的功能,因此宏的使用率不高。特别是,使用label不会阻止字节码编译(受到一些技术限制,并且允许您使用8.6或更高版本),因此您可以继续使用它而不必担心太多。这并不是说宏无法完成,而是通过在外部引入一个命令来完成它们,这些命令创建了在定义期间对它们执行宏扩展的命令(可能是程序)。一旦你以这种方式工作,你就可以对代码进行相当彻底的重新排列;输入文本根本不需要像Tcl。

Tcler的Wiki上有几页关于这个主题; http://wiki.tcl.tk/3888http://wiki.tcl.tk/11156等。我编写的一种宏观系统,我正在使用的是tclquadcode。有了这个,我就可以使用伪组装基本块标签作为类似宏的东西:它不仅涉及简单的替换,而是将相关代码重新定位到脚本体的开头,这样我就不需要手动声明前面涉及的变量(我之前发现它非常容易出错并且难以阅读);它内部使用lambda术语而不是作用域范围控制的程序,但鉴于build是宏,而不是build { my condBr [my and [my isNumericInt $x] [my isNumericInt $y]] \ $ints $doubles label ints: my ret [my add(INT,INT) [my numeric.int $x] [my numeric.int $y]] label doubles: set left [my cast(DOUBLE) $x "left"] set right [my cast(DOUBLE) $y "right"] my ret [my add(DOUBLE,DOUBLE) $left $right] } ,差异并不太重要。 Here's an example of use of that code。该代码的相关位是(如果我为可读性做了典型的替换):

apply {{func x y} {
    set ints [$func block "ints"]
    set doubles [$func block "doubles"]
    my SetCurrentBasicBlock [$func getEntryBlock]

    my condBr [my and [my isNumericInt $x] [my isNumericInt $y]] \
        $ints $doubles

    my SetCurrentBasicBlock $ints

    my ret [my add(INT,INT) [my numeric.int $x] [my numeric.int $y]]

    my SetCurrentBasicBlock $doubles

    set left [my cast(DOUBLE) $x "left"]
    set right [my cast(DOUBLE) $y "right"]
    my ret [my add(DOUBLE,DOUBLE) $left $right]
}} $func $x $y

这内部重写了很多,大概是这样的:

{{1}}

非常近似。由于调试元数据跟踪,生成的代码的真实版本是 lot 更复杂;这是一个非常重要的代码生成。