bit.c 4.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138
  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 \
  39. (unsigned)luaL_checknumber(L, 2)); \
  40. return 1; \
  41. }
  42. #define ARITHMETIC_SHIFT(name, op) \
  43. static int bit_ ## name(lua_State *L) { \
  44. lua_pushinteger(L, (lua_Integer)TOBIT(L, 1) op \
  45. (unsigned)luaL_checknumber(L, 2)); \
  46. return 1; \
  47. }
  48. MONADIC(bnot, ~)
  49. VARIADIC(band, &=)
  50. VARIADIC(bor, |=)
  51. VARIADIC(bxor, ^=)
  52. ARITHMETIC_SHIFT(lshift, <<)
  53. LOGICAL_SHIFT(rshift, >>)
  54. ARITHMETIC_SHIFT(arshift, >>)
  55. // Lua: res = bit( position )
  56. static int bit_bit( lua_State* L )
  57. {
  58. lua_pushinteger( L, ( lua_Integer )( 1 << luaL_checkinteger( L, 1 ) ) );
  59. return 1;
  60. }
  61. // Lua: res = isset( value, position )
  62. static int bit_isset( lua_State* L )
  63. {
  64. lua_UInteger val = ( lua_UInteger )luaL_checkinteger( L, 1 );
  65. unsigned pos = ( unsigned )luaL_checkinteger( L, 2 );
  66. lua_pushboolean( L, val & ( 1 << pos ) ? 1 : 0 );
  67. return 1;
  68. }
  69. // Lua: res = isclear( value, position )
  70. static int bit_isclear( lua_State* L )
  71. {
  72. lua_UInteger val = ( lua_UInteger )luaL_checkinteger( L, 1 );
  73. unsigned pos = ( unsigned )luaL_checkinteger( L, 2 );
  74. lua_pushboolean( L, val & ( 1 << pos ) ? 0 : 1 );
  75. return 1;
  76. }
  77. // Lua: res = set( value, pos1, pos2, ... )
  78. static int bit_set( lua_State* L )
  79. {
  80. lua_UInteger val = ( lua_UInteger )luaL_checkinteger( L, 1 );
  81. unsigned total = lua_gettop( L ), i;
  82. for( i = 2; i <= total; i ++ )
  83. val |= 1 << ( unsigned )luaL_checkinteger( L, i );
  84. lua_pushinteger( L, ( lua_Integer )val );
  85. return 1;
  86. }
  87. // Lua: res = clear( value, pos1, pos2, ... )
  88. static int bit_clear( lua_State* L )
  89. {
  90. lua_UInteger val = ( lua_UInteger )luaL_checkinteger( L, 1 );
  91. unsigned total = lua_gettop( L ), i;
  92. for( i = 2; i <= total; i ++ )
  93. val &= ~( 1 << ( unsigned )luaL_checkinteger( L, i ) );
  94. lua_pushinteger( L, ( lua_Integer )val );
  95. return 1;
  96. }
  97. LROT_BEGIN(bit)
  98. LROT_FUNCENTRY( bnot, bit_bnot )
  99. LROT_FUNCENTRY( band, bit_band )
  100. LROT_FUNCENTRY( bor, bit_bor )
  101. LROT_FUNCENTRY( bxor, bit_bxor )
  102. LROT_FUNCENTRY( lshift, bit_lshift )
  103. LROT_FUNCENTRY( rshift, bit_rshift )
  104. LROT_FUNCENTRY( arshift, bit_arshift )
  105. LROT_FUNCENTRY( bit, bit_bit )
  106. LROT_FUNCENTRY( set, bit_set )
  107. LROT_FUNCENTRY( clear, bit_clear )
  108. LROT_FUNCENTRY( isset, bit_isset )
  109. LROT_FUNCENTRY( isclear, bit_isclear )
  110. LROT_END( bit, NULL, 0 )
  111. NODEMCU_MODULE(BIT, "bit", bit, NULL);