Lua To Cee |
|
This utility converts a given Lua source file into an equivalent C source file written in terms of Lua C API calls. At least, this works for a large subset of the Lua language (see limitations below).
The compiler is written entirely in Lua, and no build/install is needed. This project reuses Metalua's gg/mlp parser to convert Lua source to a Metalua-style [1] AST over which the compiler then operates. lua2c does not require Metalua itself though since gg/mlp is bundled in the distribution (patched metalua-0.4.1-rc1) and is written in pure Lua.
Example usage:
lua lua2c.lua test/bisect.lua
which generates a C file similar to as shown here: [bisect.c].
You may also use the shell script "clua" to compile Lua->C->machine code and execute all in one step. However, you may need to edit the variables in the file to match your system since this utility invokes the C compiler.
./clua test/bisect.lua
lua2c can even compile itself! (Note: the -c option compiles only without running.)
./clua -c lua2c.lua # compile lua2c binary ./lua2c examples-lua/bisect.lua # test
I think this project not only is theoretically nice to have but has a number of potential uses:
WARNING: This code passes much of the Lua 5.1 test suite [7] and can compile itself, but the code is new and there can still be errors. In particular, a few language features (e.g. coroutines) are not implemented. See comments in lua2c.lua for details. Please report bugs/patches on the wiki.
lua2c does not currently support coroutines, functions that normally reject C functions (e.g. setfenv), and possibly tail call optimizations. Not all of these have the exact analogue in C. Coroutines might not ever be supported. However, some solutions might be explored [8][9], including possibly generating code that maintains the coroutine context in Lua tables.
Closures and upvalues are implemented, but creating and accessing upvalues is somewhat slow due to the implementation (see implementation notes below) and hopefully can be improved.
Now that the code is fairly complete/robust, more attention can be given to optimizing the code generation. Performance was 25%-75% of regular Lua when running a few tests [11], but hopefully future optimizations will improve that.
git clone git://github.com/davidm/lua2c.git
".
The project page is currently http://lua-users.org/wiki/LuaToCee .
(c) 2008 DavidManura. Licensed under the same terms as Lua (MIT license). See included LICENSE file for full licensing details. Please post any patches/improvements.
Some implementation notes will likely go here.
Important topics include
This project could be significantly helped by the addition of a global (per-file) code optimizer. Most importantly, some type of interprocedural data flow analysis [2] could infer the basic data types of many expressions in code (e.g. this value is a number, has no metatable, is a constant with a certain value, or is positive), especially when that code makes extensive use of local (lexical) variables. Alternately, special comments ("--!" like in LuaInspect) could be supported to allow the programmer to inject this information. If the AST is decorated with this information, the code generator could replace generic code with more specific code. For example, the Lua code "a+b" normally translates to values a and b on the Lua stack, with __add metamethod lookups. However, if a and b are known to be numbers, this can be translated directly to the C code "a+b" where a and b are C doubles on the C stack. There is no reason we shouldn't be able to achieve this type of transformation:
-- 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);
There may be some overlap with LuaJIT and other projects here [3]. For initial work in this area, see SourceOptimizer and LuaInspect.
Some syntax for embedding C expressions in-line to Lua code should also be high on the to-do list (as in Pyrex).
Coroutines should be supported, particularly given the enhancements in 5.2 (e.g. lua_callk).
Update to Lua 5.2 is recommended (see 5.2 notes above).
Unfortunately, due to time and priorities, I'm not currently actively maintaining this, besides perhaps the occasional simple bug fix, or perhaps if paid to do so. If you want to take over maintenance of this and correct the above limitations, please do so.
This package possibly would be better renamed "lua2capi" to emphasize the fact that it generates C code in the form of Lua C API calls. Another option would be to generate C code in the form of Lua internals.