lua-users home
lua-l archive

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


On 11/18/18, Luiz Henrique de Figueiredo <lhf@tecgraf.puc-rio.br> wrote:
>> There have been numerous discussions on this list for lambda
>> notations. Were any of those accompanied by a patch so that one could
>> try them out?
>
> See http://lua-users.org/lists/lua-l/2010-11/msg00808.html .
> Equivalent code for ltokenf should be straightforward.

I took a look at this filter and saw that it's not happy about
*nested* \()-functions.
Allow me to rectify this oversight.

I haven't tested it extensively, but:
% ./lua -e 'print((\f((\a(a(a)))(\x(f(\v(x(x)(v)))))))(\fac(\x(x == 0
and 1 or x*fac(x-1))))(10))'
3628800

Looks good to me.

/* proxy.c
 * lexer proxy for Lua parser -- implements nested lambdas:
 * '\x,y(\z(exp))' -> 'function (x, y) return function (z) return exp end end'
 *
 * Michael Zuo <muh.muhten@gmail.com>, 19 nov 2018:
 * This code is hereby placed in the public domain.
 *
 * Based on lhf's work: http://lua-users.org/lists/lua-l/2010-11/msg00808.html
 * Luiz Henrique de Figueiredo <lhf@tecgraf.puc-rio.br>
 * 24 Nov 2010 17:17:44
 * This code is hereby placed in the public domain.
 *
 * Add <<#include "proxy.c">> just before the definition of luaX_next in llex.c
 */

static int nexttoken (LexState *ls, SemInfo *seminfo) {
	static char needs_end[LUAI_MAXCCALLS];
	/* an early ')' will have us check needs_end[level-1] before bailing */
	static unsigned state = 0, level = 1;
	int t;

	switch (state) {
	case 0:
		t = llex(ls, seminfo);
		if (t == '\\') {
			state = 1;
			return TK_FUNCTION;
		}
		else if (t == ')' && needs_end[--level]) {
			needs_end[level] = 0;
			return TK_END;
		}
		else if (t == '(')
			level++;
		return t;
	case 1:
		state = 2;
		return '(';
	case 2:
		t = llex(ls, seminfo);
		if (t == '(') {
			needs_end[level++] = 1;
			state = 3;
			return ')';
		}
		return t;
	case 3:
		state = 0;
		return TK_RETURN;
	default: lua_assert(0); return 0;
	}
}
#define llex nexttoken