[Date Prev][Date Next][Thread Prev][Thread Next]
[Date Index]
[Thread Index]
- Subject: lua_arith with LUA_OPUNM
- From: David Manura <dm.lua@...>
- Date: Mon, 5 Jul 2010 19:40:46 -0400
On Sat, Jan 9, 2010 at 8:50 PM, Patrick Donnelly <batrick@batbytes.com> wrote:
> o lua_arith undocumented.
It's in the readme but not in the reference doc of 5.2.0work3. I've
argued for this function, as well as lua_compare, because the need
comes up in lua2c [1], it seems it should be there for orthogonality,
and its relatively easy for Lua to implement (via the private
luaO_arith/luaV_arith functions).
One thing unclear is support for the sole unary arithmetic operation
(LUA_OPUNM). Seemingly, this would be supported since lua_arith is
implemented in terms of luaO_arith, which implements it. My first
thought was to push a single value and then call lua_arith(L,
LUA_OPUNM), but as you see it always pops two values and uses the
first:
#include <lua.h>
#include <lauxlib.h>
int main() {
lua_State * L = luaL_newstate();
double f;
luaL_openlibs(L);
luaL_dostring(L, "return setmetatable({}, {__unm=function() return
2 end})");
luaL_dostring(L, "return setmetatable({}, {__unm=function() return
3 end})");
lua_arith(L, LUA_OPUNM);
f = lua_tonumber(L, -1);
printf("%f\n", f);
return 0;
}
I thought replacing the second luaL_dostring with a `lua_pushni(L)`
could be acceptable, as this is a rare operation anyway. That works
unless I also replace the first luaL_dostring with just a
`lua_pushnumber(L, 2)`, in which case the checks in lua_arith raise an
error unless I make the `lua_pushnil(L)` instead a `lua_pushnumber(L,
0)` or force it via a `if (op == LUA_OPUNM) setnvalue(L->top - 1, 0)`
near the top of lua_arith.
An alternative implementation passing only a single value might be
LUA_API void lua_arith (lua_State *L, int op) {
TValue * v1;
TValue * v2;
lua_lock(L);
v2 = L->top - 1;
if (op == LUA_OPUNM) {
v1 = v2;
api_checknelems(L, 1);
}
else {
v1 = v2 - 1;
api_checknelems(L, 2);
}
if (ttisnumber(v1) && ttisnumber(v2))
changenvalue(v1, luaO_arith(op, nvalue(v1), nvalue(v2)));
else
luaV_arith(L, v1, v1, v2, cast(TMS, op - LUA_OPADD + TM_ADD));
L->top = v1 + 1;
lua_unlock(L);
}
[1] http://lua-users.org/lists/lua-l/2009-06/msg00418.html