Implement post / pre increment / decment when translating to Lua

I am writing LSL for the Lua translator, and I am having problems with the complexity of incrementing and contracting statements. LSL has such things using the usual syntax like C (x ++, x--, ++ x, --x), but Lua does not. To avoid massive typing, I treat these types of operators as "crements". In the code below, I will use "..." to represent other parts of the expression.

... x += 1 ... 

It does not work, since Lua has a simple purpose.

 ... x = x + 1 ... 

Wont work coz that operator, and Lua cannot use expressions in expressions. LSL can use crements in expressions.

 function preIncrement(x) x = x + 1; return x; end ... preIncrement(x) ... 

As long as it gives the correct value in the expression, Lua is passed by value for numbers, so the original variable does not change. If I could make it actually change the variable, then all is well. Concerning the environment may not be such a good idea, I don't know in which area x. I think I will explore this further. The translator can display information about the area.

Assuming the above function exists -

 ... x = preIncrement(x) ... 

Does not work for the reason "this expression".

Other solutions are starting to get really dirty.

 x = preIncrement(x) ... x ... 

Works great unless the LSL source code looks something like this:

 while (doOneThing(x++)) { doOtherThing(x); } 

Which becomes a whole can of worms. Using tables in a function -

 function preIncrement(x) x[1] = x[1] + 1; return x[1]; end temp = {x} ... preincrement(temp) ... x = temp[1] 

Even randomly and has the same problems.

To begin with, I may have to actually analyze the surrounding code, and not just do simple translations to figure out what the correct way to implement any given crement will be. Has anyone got any simple ideas?

+4
source share
5 answers

After some research and reflection, I came up with an idea that might work.

For globals -

 function preIncrement(x) _G[x] = _G[x] + 1 return _G[x] end ... preIncrement("x") ... 

For locals and function parameters (which are locals to), I know that while I am parsing the crement that it is local, I can store four flags to tell which of the four racks is used in the AST variables composition. Then, when the time comes for outputting the definition of variables, I can output something like this -

 local x; function preIncrement_x() x = x + 1; return x; end function postDecrement_x() local y = x; x = x - 1; return y; end ... preIncrement_x() ... 
0
source

I think that for this you really need to do a more detailed analysis and splitting of some expressions into several operators, although many can probably be translated quite straightforwardly.

Note that, at least in C, you can defer subsequent increments / contractions to the next “point in the sequence” and place the preliminary increments / contractions to the previous point in the sequence; sequence points are located in only a few places: between operators, short-circuit operators ( && and || ), etc. (more info here)

So, fine to replace x = *y++ + z * f (); on { x = *y + z * f(); y = y + 1; } { x = *y + z * f(); y = y + 1; } { x = *y + z * f(); y = y + 1; } - the user is not allowed to assume that y will increase to anything else in the instruction, only that the value used in *y will be y before it is increased. Similarly, x = *--y + z * f(); can be replaced by { y = y - 1; x = *y + z * f (); } { y = y - 1; x = *y + z * f (); }

+1
source

Lua is designed to be very impenetrable for implementing this kind of thing. This can be done as a compiler / interpreter problem, because the interpreter can know that the variables only change when the instruction is executed.

In Lua there is no way to implement such things. Not in the general case. You can do this for global variables by passing a string to the increment function. But, obviously, this would not work for local residents or for variables that are in the global table itself.

Lua does not want you to do this; It’s best to find a way to work within the constraint. And that means code analysis.

0
source

Your proposed solution will only work when your Lua variables are global. If this is not what LSL also does, you will run into the problem of translating LSL programs that use variables called the same in different places.

Lua can only modify one lvalue for each statement - the tables passed to the functions are the only exception to this rule. You can use the local table to store all the local residents, and this will help you with the pre -... -tenses; they can be evaluated before the expression in which they are contained is invoked. But subsequent grades should be graded later, which is simply not possible in lua - at least not without some ugly code that includes anonymous functions.

So, you have one option: you must admit that some LSL instructions will be translated into several Lua statements.

Say you have an LSL instruction with the following values:

 f(integer x) { integer y = x + x++; return (y + ++y) } 

You can translate this into a Lua statement as follows:

 function f(x) { local post_incremented_x = x + 1 -- extra statement 1 for post increment local y = x + post_incremented_x x = post_incremented_x -- extra statement 2 for post increment local pre_incremented_y = y + 1 return y + pre_incremented_y y = pre_incremented_y -- this line will never be executed } 

Thus, you will basically need to add two statements for each. - crement used in your statements. For complex structures, this will mean computing the order in which expressions are calculated.

For what it's worth, I like to have decrements and predestinations as separate statements in languages. But I consider this a language flaw when they can also be used as expressions. Syntactic sugar is quickly becoming semantic diabetes.

0
source

Most of your assessment of code customizability. You are trying to hard-code data types from one to another. And call it a translator. And in all of this, you miss the regex and other pattern matching features. Which is much more present in LUA than LSL. And since the LSL code is passed to the LUA. Try using them with other features. To define a job is more like a translator than a hard passage.

Yes, I know this was asked a while ago. Although, for other viewers of this topic. Never forget the environments in which you work. EVER. Use what they give you so that you can do your best.

0
source

Source: https://habr.com/ru/post/1394551/


All Articles