我正在写一个 LSL 到 Lua 翻译器,我在实现递增和递减运算符时遇到了各种各样的麻烦。 LSL 使用通常的类似 C 的语法 (x++, x--,++x, --x) 有这样的东西,但 Lua 没有。只是为了避免大量输入,我将这些类型的运算符称为“crements”。在下面的代码中,我将使用“...”来表示表达式的其他部分。
... x += 1 ...
行不通,因为 Lua 只有简单的分配。
... x = x + 1 ...
行不通,因为这是一个语句,而且 Lua 不能在表达式中使用语句。 LSL 可以在表达式中使用增量。
function preIncrement(x) x = x + 1; return x; end
... preIncrement(x) ...
虽然它确实在表达式中提供了正确的值,但 Lua 是按值传递数字的,因此原始变量不会改变。如果我能得到它来实际改变变量,那么一切都很好。弄乱环境可能不是一个好主意,不知道范围 x 是什么。我想我接下来会调查。翻译器可以输出范围详细信息。
假设上述功能存在 -
... x = preIncrement(x) ...
不会因为“这是一个声明”的原因而工作。
其他解决方案开始变得非常困惑。
x = preIncrement(x)
... x ...
工作正常,除非原始 LSL 代码是这样的 -
while (doOneThing(x++))
{
doOtherThing(x);
}
这变成了一整 jar 蠕虫。在函数中使用表格 -
function preIncrement(x) x[1] = x[1] + 1; return x[1]; end
temp = {x}
... preincrement(temp) ...
x = temp[1]
甚至更困惑,并且有同样的问题。
开始看起来我可能必须实际分析周围的代码,而不是仅仅通过简单的翻译来找出实现任何给定 Crement 的正确方法。有人有任何简单的想法吗?
最佳答案
我认为要真正正确地做到这一点,您将不得不进行一些更详细的分析,并将一些表达式拆分为多个语句,尽管许多语句可能可以非常直接地翻译。
请注意,至少在 C 中,您可以将后递增/递减延迟到下一个“序列点”,并将前递增/递减放在前一个序列点之前;序列点仅位于几个地方:语句之间、“短路运算符”( &&
和 ||
)等 (more info here)
所以可以替换x = *y++ + z * f ();
与 { x = *y + z * f(); y = y + 1; }
——不允许用户假设y
将在语句中的任何其他内容之前递增,仅在 *y
中使用的值将是 y
在它增加之前。同样,x = *--y + z * f();
可以换成{ y = y - 1; x = *y + z * f (); }
关于lua - 转换为 Lua 时实现 post/pre increment/decrement,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/9124751/