我的用于Lua的DSL会工作吗? (这似乎太简单了)

时间:2012-03-16 21:26:12

标签: lua preprocessor dsl luajit

我非常喜欢 Lua 作为一种编程语言,但令我难以置信的是,我必须经常为所有本地变量输入“local”。

它只是让我的代码看起来更混乱。

所以我想知道,我可以在Lua之上创建一个域特定语言(DSL)来简单地使用以下变量命名约定。

  1. 如果变量名称在所有大写字母中,则它是全局变量
  2. 否则,变量是local变量
  3. 问题:这是否有效 - 是或否?

    换句话说:

    -- In Lua 5.2
    isGlobalinLua  = "is global in default Lua"
    GLOBALVAR      = "is global var in default Lua"
    local localvar = "is local var in default Lua"
    
    -- In my DSL Lua language
    isLocalinDSLLua = "is local in DSL Lua"  -- translates to: local isLocalinDSLLua = ...
    GLOBALVAR       = "is global DSL Lua"
    localvar        = "is local var in DSL Lua"  -- translates to: local localvar = ...
    

    现在,默认Lua中的以下代码:

    myglobal = 10
    local a = 1
    if a > 1 then
        local b = 2
        print b
    else
        local c = 3
        print c + myglobal
    end
    

    使用我的DSL Lua:

    MYGLOBAL = 10
    a = 1
    if a > 1 then
        b = 2
        print b
    else
        c = 3
        print c + MYGLOBAL
    end
    

    更新

    本地功能怎么样?

    以下代码如何运作?

    myfunc = function (...)   -- local myfunc = function (...)
    

    我不确定我是否希望在所有大写字母中实现所有全局功能。

    也许我只是忽略了函数并需要'local'标识符......想法?

3 个答案:

答案 0 :(得分:5)

由于您想要的更改相对简单,您基本上有两个选项。您可以试用Metalua

  

Metalua是一种提供......

的语言和编译器      
      
  • 一个完整的宏系统,类似于Lisp方言或模板Haskell所提供的功能;操纵程序可以看作是   源代码,作为抽象语法树,或作为其任意组合,   哪个更适合你的任务。
  •   
  • 一个动态可扩展的解析器,它允许您使用与其他语言完美融合的语法来支持您的宏。
  •   

或者您可以使用token filters

  

令牌过滤器的工作原理是让您有机会检查和   在他们去之前改变来自词法分析器的令牌流   解析器。你只能看到令牌而你只能生成   令牌 - 你不被允许看到文本来到词法分析器,也不允许   生成文本以进入词法分析器。

这两种方法各有利弊。 Metalua允许您在Lua中进行高级语言修改,但学习曲线更陡峭。令牌过滤器允许您对令牌流进行简单修改,但功率有限(请参阅2005 talk)。

我不确定令牌过滤器是否适合您的情况,因为在分配中的每个小写起始标识符之前插入local仅适用于简单情况。以下代码怎么样?

a = 1
a = a * a

您想将其转换为单个local,还是想要两个?

local a = 1     vs.    local a = 1
a * a                  local a = a * a  -- valid in Lua, creates a new variable

答案 1 :(得分:3)

是的,您可以这样做,但结果不称为“特定于域的语言”。它被称为“预处理器”。

我也曾经因为Lua的问题而感到难以置信 - 它缺少switchcase语句。我实际上最终修改了实现以支持此功能。但最终我觉得我并不想用我用过的方言编程。

如果您具备C编程技能,Lua实现非常简洁,实现目标的最简单方法可能就是修改实现。

答案 2 :(得分:3)

Moonscript默认情况下已将所有变量都置于本地,您只需使用export关键字来声明全局变量。它是一种非常好的下一代,类似coffeescript的语言,它编译成Lua。我在以前用过Lua的地方使用它。

foo = 'bar' -- local
square (x) -> x*x -- local

-- globals
export square
export MY_GLOBAL = 12

export class Foo
    new: (bar) => @bar = bar -- self.bar = bar
    get_bar: => @bar