我的DSL for Lua能正常工作吗...?(这似乎太简单以至于不可信)。

我非常喜欢 Lua 作为编程语言,但是,我为了所有局部变量不得不不停地打出 " local" 而感到非常麻烦。

这只会让我的代码看起来更杂乱。

所以我想知道,我能否在 Lua 顶层创建一个领域特定语言 (DSL) 来简单地应用以下变量命名约定。

  1. 如果变量名全部大写,则是全局变量
  2. 否则,该变量是一个 local 变量

问题: 这样行吗 - 是还是不是?

换句话说:

-- 在 Lua 5.2 中
isGlobalinLua  = "默认 Lua 中的全局变量"
GLOBALVAR      = "默认 Lua 中的全局变量"
local localvar = "默认 Lua 中的局部变量"

-- 在我的 DSL Lua 语言中
isLocalinDSLLua = "DSL Lua 中的局部变量"  -- 翻译成: local isLocalinDSLLua = ...
GLOBALVAR       = "DSL Lua 中的全局变量"
localvar        = "DSL Lua 中的局部变量"  -- 翻译成: 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' 标识符……你的想法是什么?

原文链接 https://stackoverflow.com/questions/9744732

点赞
stackoverflow用户221509
stackoverflow用户221509

由于你想要的变化相对简单,基本上有两种选择。你可以尝试 Metalua

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

  • 一个完整的宏系统,类似于 Lisp 方言或模板 Haskell 提供的功能;被操纵的程序可以被视为源代码、抽象语法树或二者的任意组合,以适应你的任务。
  • 一个可以动态扩展的解析器,让你的宏支持一种与语言的其他部分很好地融合的语法。

或者你可以使用 token filters

token filter 的工作方式是在进入解析器之前检查和修改从词法分析器生成的令牌流,使你只看到令牌,只允许你生成令牌 —— 你不允许查看输入到词法分析器的文本或生成要输入词法分析器的文本。

这两种方法各有利弊。Metalua 允许您在 Lua 中进行高级语言修改,但需要更多的学习成本。Token filter 允许您对令牌流进行简单的修改,但有一定的限制(请参见这里的2005年演讲)。

我不确定 token filter 是否足够胜任你的任务,因为在赋值语句中在每个以小写字母开头的标识符之前插入“local”只适用于简单情况。下面的代码该怎么处理?

a = 1
a = a * a

你想把它转换成一个“local”,还是两个?

local a = 1     vs.    local a = 1
a * a                  local a = a * a  -- 在 Lua 中是有效的,可以创建一个新变量
2012-03-16 22:02:21
stackoverflow用户41661
stackoverflow用户41661

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

我曾经也非常苦恼 Lua 中缺少 switchcase 的语句。实际上,我最终修改了实现以支持此功能。但最终我决定,我不想编写只有我自己使用的方言。

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

2012-03-17 01:48:34
stackoverflow用户152580
stackoverflow用户152580

Moonscript 已经默认将所有变量设置为本地(local),你只需要使用 export 关键字来声明全局。它是一个非常好的类似 Coffeescript 的下一代语言,编译成了 Lua。我在所有以前使用 Lua 的地方使用它。

foo = 'bar' -- 本地变量
square (x) -> x*x -- 本地变量

-- 全局变量
export square
export MY_GLOBAL = 12

export class Foo
    new: (bar) => @bar = bar -- self.bar = bar
    get_bar: => @bar
2013-04-06 21:46:06