lua-users home
lua-l archive

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


> How might i do the equivalent to c's '|' in Lua?

Someone may have some exceptionally clever way to do this.  All I have are
techniques I used to use in awk (another language that doesn't have
bitwise-or).

The best pure-Lua solution I can come up with is to construct a
two-dimensional table, with each dimension indexed by a hexadecimal
character.  The table has precomputed bitwise-or values for the two
indicies, again as a hexadecimal character.  Then, using format, convert
the two integers into hexadecimal strings.  Take each digit of the
hexadecimal strings, index into the table, get the precomputed bitwise-or
values for each nybble, and then assemble the result as a hexadecimal
string.  When done, convert the string back to a number with tonumber()'s
second argument set to 16.

This treat-numbers-as-strings is more time-efficient than decomposing the
two integers into bits, using Lua's "or" operator, and then reassembling
the bits into a number.

Of course, both of these techniques are terribly painful.  Better is to
extend Lua with bitwise operators.  Here's what I did (for Lua 4.0 alpha):

#include <stdlib.h>

#define LUA_REENTRANT

#include "lauxlib.h"
#include "lua.h"
#include "lualib.h"

#define luaL_check_uint(L,n) ((unsigned int)luaL_check_number(L, n))

#define DYADIC(name, op) \
    static void name(lua_State* L) { \
        lua_pushnumber(L, luaL_check_uint(L, 1) op luaL_check_uint(L, 2));
\
    }

#define MONADIC(name, op) \
    static void name(lua_State* L) { \
        lua_pushnumber(L, op luaL_check_uint(L, 1)); \
    }

DYADIC(intMod,      % )
DYADIC(intAnd,      & )
DYADIC(intOr,       | )
DYADIC(intXor,      ^ )
DYADIC(intShiftl,   <<)
DYADIC(intShiftr,   >>)
MONADIC(intBitNot,  ~ )

static const struct luaL_reg intMathLib[] = {
    {"imod",   intMod    },  /* "mod" already in Lua math library */
    {"band",   intAnd    },
    {"bor",    intOr     },
    {"bxor",   intXor    },
    {"bnot",   intBitNot },
    {"shiftl", intShiftl },
    {"shiftr", intShiftr },
};

extern void lua_intMathLibOpen (lua_State *L) {
    luaL_openl(L, intMathLib);
}

With this, now I can happily manipulate integers as I can in C.  And I'm
not going to have the poor speed of trying to do this entirely in Lua.