lua-users home
lua-l archive

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


There are two tools in Metalua which you should consider, either to use directly or as a source of inspiration.

First, the pattern matching extension:

match data with
| { name, x, y } -> return { sprite = '/img/'..name, x=x, y=y }
| { name} ->
    local filename = '/img/'..name
    local x, y = getDimensionsFromExternalTool(filename)
    return { sprite = filename, x=x, y=y }
| _ -> error "invalid pattern"
end

It makes data destructuring and transformation code very declarative and readable. ML-family languages, whose designs are primarily optimized to write ML-family language compilers, use it with unanimous success.

Second, the TreeQuery DSL. It's clearly optimized to handle ASTs, since that's what Metalua does the most, but it's a rather nice way to describe complex tree traversals. For instance, I wrote this yesterday, to detect all global variables in an AST semantically, rather than by grepping bytecode dumps:

    -- Complete sample available at: 
    -- https://github.com/fab13n/metalua-compiler/blob/master/samples/globals.lua  
 
    local Q = require 'metalua.treequery'      -- AST queries 
 
    local globals = { } 
    local function log_global(id, ...) [...snip, irrelevant...] end

    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_global)      -- log each of them in `globals`.

Notice that contrary to pattern matching, TreeQuery is a Lua DSL, you can use it from a plain Lua source file.

I've been working on turning Metalua into a (couple of) proper rock(s), the parser is already available as metalua-parser, and the compiler is almost ready, and in practice is available at https://github.com/fab13n/metalua-compiler.