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

nic*_*ckb 5 dsl lua preprocessor luajit

我真的很喜欢Lua作为一种编程语言,但令人难以置信的是,我必须经常local为所有局部变量键入" ".

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

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

  1. 如果变量名称在所有大写字母中,那么它是一个全局变量
  2. 否则,变量是local变量

问题:这是否有效 - 是或否?

换一种说法:

-- 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 = ...
Run Code Online (Sandbox Code Playgroud)

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

myglobal = 10
local a = 1
if a > 1 then
    local b = 2
    print b
else
    local c = 3
    print c + myglobal
end
Run Code Online (Sandbox Code Playgroud)

用我的DSL Lua:

MYGLOBAL = 10
a = 1
if a > 1 then
    b = 2
    print b
else
    c = 3
    print c + MYGLOBAL
end
Run Code Online (Sandbox Code Playgroud)

更新:

本地功能怎么样?

以下代码如何工作?

myfunc = function (...)   -- local myfunc = function (...)
Run Code Online (Sandbox Code Playgroud)

我不确定我是否希望在所有上限中实现所有全局功能.

也许我只是忽略功能并需要' local'标识符......想法?

Mic*_*man 5

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

Metalua是一种语言和编译器,提供...

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

或者您可以使用令牌过滤器:

令牌过滤器的工作原理是让您有机会在词法分析器进入解析器之前检查和更改来自词法分析器的令牌流.你只能看到令牌,你只能生成令牌 - 你不能看到文本来到词法分析器,也不能生成文本进入词法分析器.

两种方法都有其优点和缺点.Metalua允许您在Lua中进行高级语言修改,但学习曲线更陡峭.令牌过滤器允许您对令牌流进行简单修改,但功率有限(请参阅2005年的演讲).

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

a = 1
a = a * a
Run Code Online (Sandbox Code Playgroud)

你想将它转换为单个local,还是你想要两个?

local a = 1     vs.    local a = 1
a * a                  local a = a * a  -- valid in Lua, creates a new variable
Run Code Online (Sandbox Code Playgroud)


Elo*_*off 3

Moonscript默认已经拥有所有本地变量,你只需要使用export关键字来声明一个全局变量。它是一种非常好的下一代、类似咖啡脚本的语言,并且可以编译为 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
Run Code Online (Sandbox Code Playgroud)