Lua 到 C |
|
此实用程序将给定的 Lua 源文件转换为等效的 C 源文件,该文件使用 Lua C API 调用编写。至少,这适用于 Lua 语言的大部分子集(见下文限制)。
编译器完全用 Lua 编写,不需要构建/安装。该项目重用了 Metalua 的 gg/mlp 解析器,将 Lua 源代码转换为 Metalua 风格的 [1] AST,编译器随后在此基础上进行操作。lua2c 不需要 Metalua 本身,因为 gg/mlp 包含在发行版中(已修补的 metalua-0.4.1-rc1)并且是用纯 Lua 编写的。
示例用法
lua lua2c.lua test/bisect.lua
这将生成一个类似于此处所示的 C 文件:[bisect.c]。
您也可以使用 shell 脚本“clua”来编译 Lua->C->机器代码,并在一步中执行所有操作。但是,您可能需要编辑文件中的变量以匹配您的系统,因为此实用程序调用 C 编译器。
./clua test/bisect.lua
lua2c 甚至可以编译自身!(注意:-c 选项仅编译,不运行。)
./clua -c lua2c.lua # compile lua2c binary ./lua2c examples-lua/bisect.lua # test
我认为这个项目不仅在理论上很有用,而且还有许多潜在的用途。
警告:此代码通过了大部分 Lua 5.1 测试套件 [7],并且可以自行编译,但代码是新的,仍然可能存在错误。特别是,一些语言特性(例如协程)尚未实现。有关详细信息,请参见 lua2c.lua 中的注释。请在维基上报告错误/补丁。
lua2c 目前不支持协程、通常拒绝 C 函数的函数(例如 setfenv)以及可能的尾调用优化。并非所有这些在 C 中都有完全的对应物。协程可能永远不会被支持。但是,可以探索一些解决方案 [8][9],包括可能生成在 Lua 表中维护协程上下文的代码。
闭包和上值已实现,但由于实现(见下面的实现说明),创建和访问上值有点慢,希望可以改进。
现在代码已经相当完整/健壮,可以更多地关注优化代码生成。在运行一些测试 [11] 时,性能是普通 Lua 的 25%-75%,但希望未来的优化会改进这一点。
git clone git://github.com/davidm/lua2c.git
”。
项目页面目前是 https://lua-users.lua.ac.cn/wiki/LuaToCee。
(c) 2008 DavidManura。根据与 Lua 相同的条款(MIT 许可)授权。有关完整的许可详细信息,请参阅包含的 LICENSE 文件。请发布任何补丁/改进。
一些实现说明可能会放在这里。
重要主题包括
该项目可以通过添加全局(每文件)代码优化器来显著改进。最重要的是,某种形式的跨过程数据流分析[2]可以推断代码中许多表达式的基本数据类型(例如,该值是一个数字,没有元表,是一个具有特定值的常量,或者为正),尤其是在该代码大量使用局部(词法)变量时。或者,可以支持特殊注释(如LuaInspect中的“--!”)以允许程序员注入此信息。如果 AST 用此信息装饰,代码生成器可以将通用代码替换为更具体的代码。例如,Lua 代码“a+b”通常转换为 Lua 栈上的值 a 和 b,并进行 __add 元方法查找。但是,如果已知 a 和 b 为数字,则可以直接转换为 C 代码“a+b”,其中 a 和 b 为 C 栈上的 C 双精度浮点数。没有理由我们不能实现这种类型的转换。
-- Lua code local function f(n) local sum = 0 for i=1,n do sum = sum + i end -- note: sum and n are obviously always numbers. return sum end print(f(5))
// C code double sum = 0; // C datatype for(int i=1; i<=5; i++) { sum = sum + i; } // no overhead! lua_getfield(L,LUA_ENVIRONINDEX,"print"); lua_pushnumber(L,sum); lua_call(L,1,0);
这里可能与 LuaJIT 和其他项目有一些重叠[3]。有关该领域的初步工作,请参阅SourceOptimizer和LuaInspect。
在待办事项列表中,还应优先考虑在 Lua 代码中内联嵌入 C 表达式的语法(如 Pyrex 中)。
应支持协程,特别是考虑到 5.2 中的增强功能(例如 lua_callk)。
建议更新到 Lua 5.2(请参阅上面的 5.2 说明)。
不幸的是,由于时间和优先级,我目前没有积极维护它,除了偶尔的简单错误修复,或者可能是在付费的情况下。如果您想接管此项目的维护并纠正上述限制,请这样做。
此包可能最好重命名为“lua2capi”,以强调它以 Lua C API 调用形式生成 C 代码的事实。另一个选择是生成 Lua 内部形式的 C 代码。