Lua 到 Cee |
|
此工具将给定的 Lua 源文件转换为等效的 C 源文件,该文件使用 Lua C API 调用编写。至少,这适用于大部分 Lua 语言(请参阅下面的限制)。
编译器完全用 Lua 编写,无需编译/安装。该项目重用了 Metalua 的 gg/mlp 解析器,将 Lua 源转换为 Metalua 风格的 [1] AST,然后编译器在该 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 中的注释。请在 wiki 上报告错误/补丁。
lua2c 目前不支持协程、通常拒绝 C 函数的函数(例如 setfenv)以及可能的尾调用优化。其中并非所有都与 C 中完全相同。协程可能永远不支持。但是,可以探索一些解决方案 [8][9],包括可能生成在 Lua 表中维护协程上下文的代码。
闭包和 upvalue 已实现,但由于实现(参见下面的实现说明),创建和访问 upvalue 速度有些慢,并希望能够改进。
现在代码已相当完整/健壮,可以投入更多精力来优化代码生成。在运行一些测试 [11] 时,性能为普通 Lua 的 25%-75%,但希望未来的优化能有所改善。
git clone git://github.com/davidm/lua2c.git”来使用 git checkout。
项目主页目前是 https://lua-users.lua.ac.cn/wiki/LuaToCee。
(c) 2008 DavidManura。根据与 Lua (MIT 许可证) 相同的条款授权。有关完整的许可详细信息,请参阅随附的 LICENSE 文件。请发布任何补丁/改进。
一些实现说明很可能会放在这里。
重要主题包括
这个项目可以通过添加一个全局(每文件)代码优化器得到极大的帮助。最重要的是,某种类型的过程间**数据流分析** [2] 可以推断出代码中许多表达式的基本数据类型(例如,该值为数字,没有 metatable,是具有特定值的常量,或者为正),特别是当代码大量使用局部(词法)变量时。或者,可以支持特殊注释(例如,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 代码。