lua-users home
lua-l archive

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


This was not the case at all. It was related to order of code generation but not parsing or operators.

I got it to work after some more debugging and the issue was simply that `luaK_posfix` calls (indirectly) `freereg` on indexed variables. So my references became invalid when I tried to assign data to indexed variables.

The solution was to mess around a bit so that in this case I can free the registers after assigning the new data to the indexed variable.

Em qua, 21 de nov de 2018 às 08:12, Philippe Verdy <verdy_p@wanadoo.fr> escreveu:
This has to do with the way expressions are parsed, using operator priorities: the other operators are generating thier own code in order you do not expect.

Le lun. 19 nov. 2018 à 20:36, Felipe Tavares <felipe.oltavares@gmail.com> a écrit :
Hi!

I am writing an lightweight (and bare bones) implementation of the += operator.

I already got it working, many thanks to the power patch by Olsen (1542655470.local-2711d4b8-ab3c-v1.5.1-da141eaf@getmailspring.com/0?redirect=http%3A%2F%2Flua-users.org%2Ffiles%2Fwiki_insecure%2Fpower_patches%2F5.2%2Fcompound-5.2.2.patch&recipient=bHVhLWxAbGlzdHMubHVhLm9yZw%3D%3D" title="http://lua-users.org/files/wiki_insecure/power_patches/5.2/compound-5.2.2.patch" target="_blank">http://lua-users.org/files/wiki_insecure/power_patches/5.2/compound-5.2.2.patch).

Diferently from Olsen, I added an extra token (TK_PLUSEQ) to the parser, and then in the assignment routine in lparser.c I did this:

static void assignment (LexState *ls, struct LHS_assign *lh, int nvars) {
expdesc e;
check_condition(ls, vkisvar(lh->v.k), "syntax error");
...
/* Language extension here */
else if (testnext(ls, TK_PLUSEQ)) {
// Get the rvalue _expression_
expr(ls, &e);
// Add it with the lvalue of the assignment
luaK_infix(ls->fs, OPR_ADD, &e);
luaK_posfix(ls->fs, OPR_ADD, &e, &lh->v, ls->linenumber);
// Store it back
luaK_storevar(ls->fs, &lh->v, &e);
return; /* avoid default */
}

...

Now, this works, but not in all cases:

Works:

local x = 1
x += 1

Doesn't (has no effect on the value of y.y):

local y = {
y = 1
}
y.y += 1

Doesnt (has no effect on z.z.z):

local z = {
z = {
z = 1
}
}

z.z.z += 1

I have no idea why it works in some cases and in others it doesn't; I am guessing it has something to do with the way the variable (lh->v) is actually represented?
Open Tracking


--
--
Felipe Tavares