lua-users home
lua-l archive

Re: First class : (was Re: Regarding the name 'pairs')

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


On Sep 14, 2009, at 10:44 PM, Mark Hamburg wrote:
On Sep 14, 2009, at 5:26 AM, steve donovan wrote:
On Mon, Sep 14, 2009 at 2:16 PM, Luiz Henrique de Figueiredo
<lhf@tecgraf.puc-rio.br> wrote:
One important reason for not having "set:values" is that it'd be sugar
for "function (...) return set:values(...) end" and this would imply
the creation of a hidden closure.
Yes, it did feel like an incompatible proposal.
So, is there some support for Mark Hamburg's closure sugar in Rio ;) ?
To be fair, though I'm not sure to whom, I think someone promoted it before I did. ;-)
But the full details of my proposal included:
1. Binds early.
2. Binds strongly. (Weak closures are a separate implementation problem.) 3. Only generates a closure when not used at a call site though this should be purely an optimization. The piece of syntax I will take credit for promoting since I don't think I'd seen it elsewhere before is:
	obj:[method](...)
and in this case:
	obj:[method]
Thereby allowing the method name to be an expression while at the same time not forcing the repetition of obj in an expansion of the colon operator. I believe this is actually moderately easy to implement as a patch on the current Lua implementation. (I'd have to go find my notes on how to do so.)
In primaryexp (lparser.c), the colon operator case becomes:
 case ':': { /* `:' NAME funcargs */
 expdesc key;
 luaX_next(ls);
		/* PATCH: Add support for obj:[ exp ] syntax for calling methods. */
		if (ls->t.token == '[') {
		 yindex(ls, &key);
		}
		else {
		 checkname(ls, &key);
		}
 luaK_self(fs, v, &key);
/* Compiles each expression evaluating them into a sequence of registers. */ switch (ls->t.token) { /* PATCH: Check for a call before going to the funcargs case, otherwise curry. */
		 case '(': case TK_STRING: case '{': { /* funcargs */
		 funcargs(ls, v);
			break;
		 }
		 default: {
		 currymethod(ls, v);
			return;
		 }
 }
 break;
 }
I'm afraid I don't have an implementation for currymethod. Without that support, the inner switch just becomes a call to funcargs(ls,v). But to get the rest of obj:[ method ] working one also needs to revise luaK_self in lcode.c:
void luaK_self (FuncState *fs, expdesc *e, expdesc *key) {
 int func;
 luaK_exp2anyreg(fs, e);
 freeexp(fs, e);
 func = fs->freereg;
 luaK_reserveregs(fs, 2);
 luaK_codeABC(fs, OP_SELF, func, e->u.s.info, luaK_exp2RK(fs, key));
 freeexp(fs, key);
fs->freereg = func + 2; /* PATCH: Make sure that freeing the key won't have just cost us a register. Why??? */
 e->u.s.info = func;
 e->k = VNONRELOC;
}
As the comments, suggest it would be good to have someone who knows the register behavior in the Lua code generator better than I review this code.
Mark

AltStyle によって変換されたページ (->オリジナル) /