lua-users home
lua-l archive

[Date Prev][Date Next][Thread Prev][Thread Next] [Date Index] [Thread Index]

I'm pleased to announce the availability of Metalua 0.7.2:

Metalua is a compiler for a superset of the Lua language, which supports compile-time metaprogramming: a source file can extend the language with new syntaxes on-the-fly, while being compiled. Such syntaxes can be packaged into extension modules, for easy distribution and reuse.

It is also a Lua program manipulation library: it generates and manipulates Abstract Syntax Trees (AST), decorated with source code pointers, which allow high-level analysis and manipulation of Lua programs. Besides converting between source, AST and bytecode formats, it offers some libraries such as `metalua.treequery`, which allow to analyze and modify ASTs. For instance, the following program finds and returns the names of all global variables occurring in a source file:

    function all_globals(filename)
        local globals = { }
        local log     = function() globals[identifier[1]] = true end
        local mlc     = require 'metalua.compiler'.new() -- compiler
        local Q       = require 'metalua.treequery'      -- AST queries
        local ast     = mlc :srcfile_to_ast (filename)

        Q(ast)                         -- globals are...
            :filter     'Id'           -- ...nodes with tag 'Id'...
            :filter_not (Q.is_binder)  -- ...which are not local binders...
            :filter_not (Q.get_binder) -- ...and aren't bound;
            :foreach    (log)          -- log each of them in `globals`.

        return globals

(A more complete, useful version of this program is available as

Metalua is used as a Lua code analysis tool in projects like LuaDevelopmentTools (the Eclipse-based Lua IDE), LuaDocumentor (an LDoc-like tool which retrieves information missing from comments through code analysis), LuaInspect (back-end for SciTE and ZeroBrane) , etc.

Language extensions wise, Metalua comes with two substantial extension modules:

    -{ extension('comprehension', ...) }
    even = { i for i=1, 100 if i%2==0 }

It also supports improved loops, by allowing to compose their headers:

    for i=1, 10 for j=1,10 if i~=j until i+j>17 do print(i,j) end

In such loops, `break` statements are handled gracefully (and  `continue` statements are accepted ;-))

    match ast with
    | `Function{ args, body } -> do_stuff_with(args, body)
    | `Number{ 0 } -> print "this is a zero"
    | `Do{ ... } -> print("block of "'#', ...).." statements)
    | x -> print("Don't know what to do with a "..tostring(x.tag))

In contrast to previous versions of Metalua, this version requires no compilation nor bootstrapping step to be installed: put the `metalua/` directory in your `$LUA_PATH`, and it works.

Libraries written in Metalua can be loaded from plain Lua ones by first performing `require "metalua.loader"` (or passing option `-lmetalua.loader` to the Lua interpreter), which will extend `package.loaders`. They can also be precompiled into bytecode, to be loaded by the regular Lua loader.

For convenience, Metalua has been cut in two separate Lua rocks: