diff --git a/src/modules/bit.c b/src/modules/bit.c index 509dc845..293742f7 100644 --- a/src/modules/bit.c +++ b/src/modules/bit.c @@ -4,6 +4,15 @@ // Modified by BogdanM for eLua +// TH: Fixed various places to do all conversions to/from lua numbers as unsigned +// This is also consitent with other parts of eLua e.g. the cpu module +// If have also considered using signed integers like in http://bitop.luajit.org/ +// This would have the advantage that the behaviour for lua "long" would be +// identical to lua "double". But it also a lot of drawbacks, and would be inconsistent +// with e.g. the cpu.r/w operations, because they expect unsigned numbers. +// +// In addtion I added the tohex and rotate functions from http://bitop.luajit.org/ + #include @@ -71,6 +80,17 @@ void bit_pushuinteger(lua_State *L, lua_UInteger n) (unsigned)luaL_checknumber(L, 2)); \ return 1; \ } + +// Added TH +#define BIT_SH(name, fn) \ + static int bit_ ## name(lua_State *L) { \ + bit_pushuinteger(L, fn((lua_UInteger)TOBIT(L, 1), \ + (unsigned)luaL_checknumber(L, 2))); \ + return 1; \ + } + +#define brol(b, n) ((b << n) | (b >> (32-n))) +#define bror(b, n) ((b << (32-n)) | (b >> n)) MONADIC(bnot, ~) VARIADIC(band, &=) @@ -80,6 +100,11 @@ ARITHMETIC_SHIFT(lshift, <<) LOGICAL_SHIFT(rshift, >>) ARITHMETIC_SHIFT(arshift, >>) +BIT_SH(rol, brol) // TH +BIT_SH(ror, bror) // TH + + + // Lua: res = bit( position ) static int bit_bit( lua_State* L ) { @@ -131,6 +156,21 @@ static int bit_clear( lua_State* L ) return 1; } +//TH: "Borrowed" from luaBitop +static int bit_tohex(lua_State *L) +{ + lua_UInteger b = ( lua_UInteger )TOBIT( L, 1 ); + int n = lua_isnone(L, 2) ? 8 : luaL_checkinteger(L, 2); + const char *hexdigits = "0123456789abcdef"; + char buf[8]; + int i; + if (n < 0) { n = -n; hexdigits = "0123456789ABCDEF"; } + if (n > 8) n = 8; + for (i = (int)n; --i >= 0; ) { buf[i] = hexdigits[b & 15]; b >>= 4; } + lua_pushlstring(L, buf, (size_t)n); + return 1; +} + #define MIN_OPT_LEVEL 2 #include "lrodefs.h" const LUA_REG_TYPE bit_map[] = { @@ -146,9 +186,13 @@ const LUA_REG_TYPE bit_map[] = { { LSTRKEY( "clear" ), LFUNCVAL( bit_clear ) }, { LSTRKEY( "isset" ), LFUNCVAL( bit_isset ) }, { LSTRKEY( "isclear" ), LFUNCVAL( bit_isclear ) }, + { LSTRKEY( "tohex" ), LFUNCVAL( bit_tohex ) }, // TH + { LSTRKEY("rol"), LFUNCVAL(bit_rol) }, // TH + { LSTRKEY("ror"), LFUNCVAL(bit_ror) }, // TH { LNILKEY, LNILVAL} }; + LUALIB_API int luaopen_bit (lua_State *L) { LREGISTER( L, "bit", bit_map ); }