bit.c 4.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136
  1. /* Bitwise operations library */
  2. /* (c) Reuben Thomas 2000-2008 */
  3. /* See README for license */
  4. // Modified by BogdanM for eLua
  5. #include "module.h"
  6. #include <limits.h>
  7. #include "lauxlib.h"
  8. /* FIXME: Assume size_t is an unsigned lua_Integer */
  9. typedef size_t lua_UInteger;
  10. #define LUA_UINTEGER_MAX SIZE_MAX
  11. /* Define TOBIT to get a bit value */
  12. #define TOBIT(L, n) \
  13. (luaL_checkinteger((L), (n)))
  14. /* Operations
  15. The macros MONADIC and VARIADIC only deal with bitwise operations.
  16. LOGICAL_SHIFT truncates its left-hand operand before shifting so
  17. that any extra bits at the most-significant end are not shifted
  18. into the result.
  19. ARITHMETIC_SHIFT does not truncate its left-hand operand, so that
  20. the sign bits are not removed and right shift work properly.
  21. */
  22. #define MONADIC(name, op) \
  23. static int bit_ ## name(lua_State *L) { \
  24. lua_pushinteger(L, op TOBIT(L, 1)); \
  25. return 1; \
  26. }
  27. #define VARIADIC(name, op) \
  28. static int bit_ ## name(lua_State *L) { \
  29. int n = lua_gettop(L), i; \
  30. lua_Integer w = TOBIT(L, 1); \
  31. for (i = 2; i <= n; i++) \
  32. w op TOBIT(L, i); \
  33. lua_pushinteger(L, w); \
  34. return 1; \
  35. }
  36. #define LOGICAL_SHIFT(name, op) \
  37. static int bit_ ## name(lua_State *L) { \
  38. lua_pushinteger(L, (lua_UInteger)TOBIT(L, 1) op luaL_checkunsigned(L, 2)); \
  39. return 1; \
  40. }
  41. #define ARITHMETIC_SHIFT(name, op) \
  42. static int bit_ ## name(lua_State *L) { \
  43. lua_pushinteger(L, (lua_Integer)TOBIT(L, 1) op luaL_checkunsigned(L, 2)); \
  44. return 1; \
  45. }
  46. MONADIC(bnot, ~)
  47. VARIADIC(band, &=)
  48. VARIADIC(bor, |=)
  49. VARIADIC(bxor, ^=)
  50. ARITHMETIC_SHIFT(lshift, <<)
  51. LOGICAL_SHIFT(rshift, >>)
  52. ARITHMETIC_SHIFT(arshift, >>)
  53. // Lua: res = bit( position )
  54. static int bit_bit( lua_State* L )
  55. {
  56. lua_pushinteger( L, ( lua_Integer )( 1 << luaL_checkinteger( L, 1 ) ) );
  57. return 1;
  58. }
  59. // Lua: res = isset( value, position )
  60. static int bit_isset( lua_State* L )
  61. {
  62. lua_UInteger val = luaL_checkunsigned( L, 1 );
  63. unsigned pos = ( unsigned )luaL_checkinteger( L, 2 );
  64. lua_pushboolean( L, val & ( 1 << pos ) ? 1 : 0 );
  65. return 1;
  66. }
  67. // Lua: res = isclear( value, position )
  68. static int bit_isclear( lua_State* L )
  69. {
  70. lua_UInteger val = luaL_checkunsigned( L, 1 );
  71. unsigned pos = ( unsigned )luaL_checkinteger( L, 2 );
  72. lua_pushboolean( L, val & ( 1 << pos ) ? 0 : 1 );
  73. return 1;
  74. }
  75. // Lua: res = set( value, pos1, pos2, ... )
  76. static int bit_set( lua_State* L )
  77. {
  78. lua_UInteger val = luaL_checkunsigned( L, 1 );
  79. unsigned total = lua_gettop( L ), i;
  80. for( i = 2; i <= total; i ++ )
  81. val |= 1 << ( unsigned )luaL_checkinteger( L, i );
  82. lua_pushinteger( L, ( lua_Integer )val );
  83. return 1;
  84. }
  85. // Lua: res = clear( value, pos1, pos2, ... )
  86. static int bit_clear( lua_State* L )
  87. {
  88. lua_UInteger val = luaL_checkunsigned( L, 1 );
  89. unsigned total = lua_gettop( L ), i;
  90. for( i = 2; i <= total; i ++ )
  91. val &= ~( 1 << ( unsigned )luaL_checkinteger( L, i ) );
  92. lua_pushinteger( L, ( lua_Integer )val );
  93. return 1;
  94. }
  95. LROT_BEGIN(bit, NULL, 0)
  96. LROT_FUNCENTRY( bnot, bit_bnot )
  97. LROT_FUNCENTRY( band, bit_band )
  98. LROT_FUNCENTRY( bor, bit_bor )
  99. LROT_FUNCENTRY( bxor, bit_bxor )
  100. LROT_FUNCENTRY( lshift, bit_lshift )
  101. LROT_FUNCENTRY( rshift, bit_rshift )
  102. LROT_FUNCENTRY( arshift, bit_arshift )
  103. LROT_FUNCENTRY( bit, bit_bit )
  104. LROT_FUNCENTRY( set, bit_set )
  105. LROT_FUNCENTRY( clear, bit_clear )
  106. LROT_FUNCENTRY( isset, bit_isset )
  107. LROT_FUNCENTRY( isclear, bit_isclear )
  108. LROT_END(bit, NULL, 0)
  109. NODEMCU_MODULE(BIT, "bit", bit, NULL);