lua-users home
lua-l archive

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

Hi all,

This is the second beta release of LuaMacro 2, yet another Lpeg-driven
syntactical candy store for Lua. A few bugs squished (like 'elseif'
not been recognized as a keyword) and some nice generalizations: for
instance, you can define new tokens (like '@@') and use them as
macros. Operator macros can be pass-through, so that you can safely
overload standard Lua tokens like '{' and '.'.

The front-end luam also sets a custom package loader, as suggested by
Alexander. So if require 'fred' fails, the package loader will look
for fred.m.lua and preprocess and load that.

There is an interactive prompt:

$> luam -i
Lua 5.1.4  Copyright (C) 1994-2008, PUC-Rio
Lua Macro 2.1 Copyright (C) 2007-2011 Steve Donovan
> require 'macro.all'
> forall i in {10,20,30} do print(i) end
> f = \x(x+1)
> = f(10)

There was recent discussion around new control structures, and I still
think that a macro facility provides the best laboratory for
experimentation.  For instance, a simple case statement is a one-line

def_ case(x) do def_ (of elseif _value ==) local _value = x if false
then _END_END_

function test(n)
    local res
    of 10 then
        res = 1
    of 20 then
        res = 2
        res = 3
    return res

The 'of' is simply defined as an elseif (but notice that it is defined
within the scope of the case macro, and will _not_ exist outside the
case block)  The _END_END_ is a built-in macro that ensures that the
final 'end' causes another 'end' to be emitted and closing the do
block. (So we don't have to do unnatural things like 'endcase')

Here is a 'with' statement

with aLongName do
   .x = 1
   .y = 2

Note the periods; we could fool with dynamic scope at this point (and
macros can smooth over the differences here between 5.1 and 5.2) but
personally I was burnt too often by the Pascal with statement; this is
one of the few places where Visual Basic syntax is better, IHMO.

The idea is to look at the token just before each period and decide
whether we should insert a table reference before it. Basically, if
the last token is not a name or ']' then we go ahead.  Everything is
put inside a do block with a local alias to the expression.

    local lt,lv = M.last_token() --  peek before the period...
    if lt ~= 'iden' and lt ~= ']' then -- complete the table lookup
      return '_var.'
      return nil,true -- pass through
  local expr = get:upto 'do'
  return 'do local _var = '..tostring(expr)..'; '

I agree that this is a little bit hacky. But the new meaning of '.'
again does not escape the with block so it cannot do arbitrary damage

It's now possible to completely re-skin Lua - an example is here:

Basically, cskin.lua defines a simple curly-braces version of Lua with
OOP in about 140 lines.

Personally, I think it's a bit scary and overboard. But it was an
interesting technical challenge ;)  As always, don't use excessive
syntactical sugar if on a kilocalorie-restricted diet. Ask your health
professional if in doubt.

steve d.