lua-users home
lua-l archive

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


If your special vectors are always accessed with multiple indexes, they can be distinguished at compile-time and handled properly by a metalua macro (metalua lets you perform arbitrary code manipulation and syntax extension at compile time, and is bytecode and source compatible with Lua 5.1).

What you can do is remove the { '[', mlp.expr, ']' } _expression_ suffix parser, and replace it with your own { '[', mlp.expr_list, ']' }. If the expr_list happens to be of length one, compile it to the regular stuff. If there are more than one index value, compile it to a vector getter.

Then there is the problem of using these as left-values on assignments. The simplest way, although not the cleanest one, would probably be to modify the '=' assignment operator: if the left argument is a vector getter, turn it into a setter.
-- Warning, untested code. Todo: provide your own:
-- * vector_getter_builder(vector_expr, indexes_list)
-- * change_getter_into_setter(getter, value_to_set)
-- * is_vector_getter(expr)

-- back-end: buid getters or regular indexed expressions
function idx_builder(expr, suffix) local indexes = unpack(suffix)
if #indexes==1 then return `Index{expr, indexes[1]}
else return vector_getter_builder(expr, indexes) end
end

-- front-end: plug the syntax in
mlp.expr.suffix:del '['
mlp.expr.suffix:add{ "[", mlp.expr_list, "]", builder = idx_builder }

-- Hack the assignment: if there's a getter on the left, change it into a setter
function set_builder (left, right)
if is_vector_getter(left[1]) then
if #left>1 then error "multiple assignments left as an exercice to the reader :)" end
return change_getter_into_setter(left[1], right[1])
else
return `Set{ left, right }
end
end
mlp.stat.assignments["="] = set_builder

However, the code above is not really clean:
- changing vector getters into setters is conceptually hackish, and it's not unlikely that I overlooked some corner cases.
- this parser changes some standards parser bits ("[...]" and "="). If other macros decide to also change them, in different ways, then they'll be incompatible with yours. This might or might not be an issue, depending on your use case: reusable/modular code is generally harder to write...

The proper way would be to:
- build your own separate syntax, e.g. vector&[1, x]
- make it handle assignments by itself, by checking for the presence of a "=" after the "]", instead of messing with the default assignment.

Notice that there is a clist extension in the distribution, which among others extends the [ ] suffix notation; but no care has been taken yet to make it produce efficient code, and it only deals with regular lists, not udata.
Usage sample: http://repo.or.cz/w/metalua.git?a=blob_plain;f=src/samples/clist_test.mlua;hb=HEAD
Implementation: http://repo.or.cz/w/metalua.git?a=blob_plain;f=src/lib/extension/clist.mlua;hb=HEAD

Finally, there is a user manual documenting the basics of metalua programming, as well as the code manipulation libraries: http://metalua.luaforge.net/manual000.html

-- Fabien.