lua-users home
lua-l archive

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


I've tried to create the magical function you want. A better solution with the modified environment is in the other mail from PA.

------------------------------------------------------------------------------
local my_dsl =
{
	op1 = function(var) return "foo"..var end;
	op2 = function(var) return "bar"..var end;
	op3 = function(var) return "baf"..var end;
};

function in_context_of(dsl)
	-- Return an anonymous function which will have dsl as an upvalue
	return function (array)
		-- Build the table you want
		local ret = {}
		for ab,list in pairs(array) do
			-- ab is "Alpha" or "Beta"
			ret[ab] = {}
			for i=1,table.getn(list),2 do
				local op = list[i]
				local arg = list[i+1]
				table.insert(ret[ab], dsl[op](arg))
			end
		end
		return ret
	end
end

-- Syntax is a bit more complicated that what you exacly want
local Foo = in_context_of(my_dsl)
{
	["Alpha"] = { 'op1', "a", 'op2', "b" };
	["Beta"] = { 'op2', "a", 'op1', "b", 'op3', "c" };
};

-- Display the result
for k,ops in pairs(Foo) do
	for _,v in pairs(ops) do
		io.write(" "..v)
	end
	io.write("\n")
end 

-- Tested, this works!

------------------------------------------------------------

Doub.


-----Message d'origine-----
De : lua-bounces@bazar2.conectiva.com.br [mailto:lua-bounces@bazar2.conectiva.com.br] De la part de Alexander Gladysh
Envoyé : 15 mars 2006 13:43
À : Lua list
Objet : Some syntax troubles

Hi, all!

I'm using Lua 5.0.2.

I'm trying to create a small local DSL for one of my tables in following form:

local Foo =
{
  ["Alpha"] = { op1 "a", op2 "b" };
  ["Beta"] = { op2 "a", op1 "b", op3 "c" }; }

I need to declare opN functions somewhere. As they wouldn't be used in such context anywhere else, and they should have convenient short and common names, I want to have their scope as local as possible.

I've tried to put them right into the Foo table:

local Foo =
{
  op1 = function(var) ... end;
  op2 = function(var) ... end;
  op3 = function(var) ... end;

  ["Alpha"] = { op1 "a", op2 "b" };
  ["Beta"] = { op2 "a", op1 "b", op3 "c" }; }

But this 1) reduces readability of declarative code in Foo table, and
2) obviously wouldn't work, since AFAICS at the time when inner tables ctors are called, outer table members are still not initialized.

What I want can be done by moving opN definitions outside of Foo (as local functions), and enclosing them along with Foo table constructor inside some scope:

local MakeFoo = function()
  op1 = function(var) ... end;
  op2 = function(var) ... end;
  op3 = function(var) ... end;

  return
  {
    ["Alpha"] = { op1 "a", op2 "b" };
    ["Beta"] = { op2 "a", op1 "b", op3 "c" };
  }
end

local Foo = MakeFoo();

But this obfuscates the code a bit.

Furthermore, I'd like to write something like:

local my_dsl =
{
  op1 = function(var) ... end;
  op2 = function(var) ... end;
  op3 = function(var) ... end;
};

local Foo = in_context_of(my_dsl)
{
  ["Alpha"] = { op1 "a", op2 "b" };
  ["Beta"] = { op2 "a", op1 "b", op3 "c" }; };

Where 'in_context_of' is some "magic" function, which return functor, which makes members of my_dsl visible for created table. (Simpler call would be in_context_of(my_dsl, { ... }).)

However, I do not see how this can be done, since function arguments are evaluated before function call is done. May be some kind of 'using' declaration construct would help here, but this requires at least one next release of Lua, and I need solution now. :)

Definitions of opN can be separated from table-constructing function by passing them as a table parameter:

local my_dsl =
{
  op1 = function(var) ... end;
  op2 = function(var) ... end;
  op3 = function(var) ... end;
};

local Foo = function(c)
  return
  {
    ["Alpha"] = { c.op1 "a", c.op2 "b" };
    ["Beta"] = { c.op2 "a", c.op1 "b", c.op3 "c" };
  }
end(my_dsl);

Looks weird though. I'd say, that some macroses would help to hide weird prologue and epilogue, and some 'with'-like construct would help to remove that ugly 'c.' prefix. But Lua does not have neither construct.

Any suggestions?

Thanks in advance,
Alexander.