有 Lua DSL 的条件?

Having conditionals for a Lua DSL?

我正在尝试使用条件在 Lua 中构建小型 DSL。

x = '0'
function start ()
    return function () end
end

function set_x (v)
    x = v
    return function () end
end

function if_x (v)
    if x == v then
        print ("x = ", v)
    else
        print ("x != ", v)
    end
    return function () end
end

-- DSL here
start {
    set_x '10',
    if_x '10' { print ('x is 10') },
    if_x '20' { print ('x is 20') }
}

输出为:

x =     10
x is 10
x !=    20
x is 20

如何以优雅的方式实现条件,以便不打印 x is 20?如果不在 set_x 中设置全局变量并在 if_x 中检查它,我无法做到这一点,但这看起来很难看。

有什么线索吗?

谢谢!

你必须看看你的 EDSL 对 Lua 的看法;让我们剖析有问题的陈述

if_x '20' { print ('x is 20') }

我们可以使用 "regular" 语法重写它:

if_x('20')({ 1 = print('x is 20') })

我添加了 1 = 来展示有问题的部分;数组的构造需要评估打印语句 不管 您的条件如何。

为了让它工作,你实际上需要一个 lambda:

start {
    set_x '10',
    if_x '10' { function() print ('x is 10') end },
    if_x '20' { function() print ('x is 20') end }
}

然后可以有条件地调用:

function if_x (v)
    if x == v then
        print ("x = ", v)
        return function (block) block[1]() end
    else
        print ("x != ", v)
        return function () end
    end 
end

不是很漂亮,但我不认为你可以摆脱它,因为任何没有用 lambda 包裹的表达式都需要执行。您可以尝试使用条件运算符的短路行为,但是您无法进一步传递代码,因为它总是会在函数边界处被计算。

See Live on Ideone

w=12=will.y.w=11=w w=10=sh