Lua To Cee

lua-users home
wiki

lua2c is a Lua module and utility to convert Lua 5.1 source code to C API code.

Description

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.

Usage

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

Related Work

Potential Uses

I think this project not only is theoretically nice to have but has a number of potential uses:

Limitations

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.

Lua 5.2 Notes

Download

Project Page

The project page is currently http://lua-users.org/wiki/LuaToCee .

Author

DavidManura

Licensing

(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.

Implementation Notes

Some implementation notes will likely go here.

Important topics include

Future Work

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).

Status

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.

Naming

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.

References


RecentChanges · preferences
edit · history
Last edited September 1, 2010 8:05 am GMT (diff)