[Date Prev][Date Next][Thread Prev][Thread Next]
[Date Index]
[Thread Index]
- Subject: Re: help to (slightly) modify Lua interpreter
- From: Mark Feldman <mfeldman@...>
- Date: Mon, 09 Nov 2009 13:17:30 +1100
steve donovan wrote:
This is in fact the case that makes this so non-trivial. It is not
difficult to do a token-filter that copes with the difference between
A[i,j] and A[i,j] = value, but multiple assignment needs a proper AST
transformation.
I created a patch for multi-dimensional indexing over the weekend (see
code below) and pretty-much reached the same conclusion. I eventually
gave up on using multiple parameters for the indexing and instead
modified the parser to treat m[1,2] the same as m[1][2]. Apart from
being a very small patch (and faster to parse) it doesn't break multiple
assignment or constructors. Of course, I personally would hope that this
never officially makes it into Lua because it forces a very specific and
unnessessary syntax onto the language IMHO, but for the time being it
would probably be good enough for what Francesco is after.
As far as the technical implementation goes my patch does 3 things:
1) The yindex function (which parses table indices) has been modified so
that it doesn't parse the outer '[' and ']' tokens. This is now handled
by the calling functions.
2) The loop in primaryexp has been modified to keep looping and indexing
while the ',' token is encountered.
3) The recfield function has had a couple of lines added so that parsing
of constructors remains the same. Statements such as m={[1][2]="foo"}
could technically be made to work but they're nonsensical and would fail
since m[1] is nil to begin with. Also the existing parser doesn't allow
statements such as m={[1]={}, [1][2]="foo"} so I've kept that behaviour
the same.
I haven't tested this patch exhaustively but looking at the way the code
works I think it should be ok, it seems to have no problem handling code
like this:
-- test multidimensional arrays. also test constructors
-- and multiple assignment to show they're not broken
m = {[1]={}, [2]="foo"}
m[1,2] = "bar"
print(m[2], m[1][2], m[1,2]) --> foo bar bar
m.foo = {}
m.foo.bar = "grok"
print(m["foo","bar"]) --> grok
Cheers,
Mark Feldman
=== mda.patch===
diff C:\Temp\lua-5.1.4\src/lparser.c lua-5.1.4\src/lparser.c
420d419
< luaX_next(ls); /* skip the '[' */
423d421
< checknext(ls, ']');
453a452,453
> {
> luaX_next(ls);
454a455,456
> checknext(ls, ']');
> }
703,705c705,712
< luaK_exp2anyreg(fs, v);
< yindex(ls, &key);
< luaK_indexed(fs, v, &key);
---
> luaX_next(ls);
> do
> {
> luaK_exp2anyreg(fs, v);
> yindex(ls, &key);
> luaK_indexed(fs, v, &key);
> } while (testnext(ls, ','));
> checknext(ls, ']');
This message and its attachments may contain legally privileged or confidential information. This message is intended for the use of the individual or entity to which it is addressed. If you are not the addressee indicated in this message, or the employee or agent responsible for delivering the message to the intended recipient, you may not copy or deliver this message or its attachments to anyone. Rather, you should permanently delete this message and its attachments and kindly notify the sender by reply e-mail. Any content of this message and its attachments, which does not relate to the official business of the sending company must be taken not to have been sent or endorsed by the sending company or any of its related entities. No warranty is made that the e-mail or attachment(s) are free from computer virus or other defect.