lbitlib.c 2.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123
  1. /*
  2. ** $Id: $
  3. ** Standard library for bitwise operations
  4. ** See Copyright Notice in lua.h
  5. */
  6. #include "lua.h"
  7. #include "lauxlib.h"
  8. #include "lualib.h"
  9. /* number of bits considered when shifting/rotating (must be a power of 2) */
  10. #define NBITS 32
  11. typedef LUA_INT32 b_int;
  12. typedef unsigned LUA_INT32 b_uint;
  13. static b_uint getuintarg (lua_State *L, int arg) {
  14. b_uint r;
  15. lua_Number x = lua_tonumber(L, arg);
  16. if (x == 0) luaL_checktype(L, arg, LUA_TNUMBER);
  17. lua_number2uint(r, x);
  18. return r;
  19. }
  20. static b_uint andaux (lua_State *L) {
  21. int i, n = lua_gettop(L);
  22. b_uint r = ~(b_uint)0;
  23. for (i = 1; i <= n; i++)
  24. r &= getuintarg(L, i);
  25. return r;
  26. }
  27. static int b_and (lua_State *L) {
  28. b_uint r = andaux(L);
  29. lua_pushnumber(L, lua_uint2number(r));
  30. return 1;
  31. }
  32. static int b_test (lua_State *L) {
  33. b_uint r = andaux(L);
  34. lua_pushboolean(L, r != 0);
  35. return 1;
  36. }
  37. static int b_or (lua_State *L) {
  38. int i, n = lua_gettop(L);
  39. b_uint r = 0;
  40. for (i = 1; i <= n; i++)
  41. r |= getuintarg(L, i);
  42. lua_pushnumber(L, lua_uint2number(r));
  43. return 1;
  44. }
  45. static int b_xor (lua_State *L) {
  46. int i, n = lua_gettop(L);
  47. b_uint r = 0;
  48. for (i = 1; i <= n; i++)
  49. r ^= getuintarg(L, i);
  50. lua_pushnumber(L, lua_uint2number(r));
  51. return 1;
  52. }
  53. static int b_not (lua_State *L) {
  54. b_uint r = ~getuintarg(L, 1);
  55. lua_pushnumber(L, lua_uint2number(r));
  56. return 1;
  57. }
  58. static int b_shift (lua_State *L) {
  59. b_uint r = getuintarg(L, 1);
  60. lua_Integer i = luaL_checkinteger(L, 2);
  61. if (i < 0) { /* shift right? */
  62. i = -i;
  63. if (i >= NBITS) r = 0;
  64. else r >>= i;
  65. }
  66. else { /* shift left */
  67. if (i >= NBITS) r = 0;
  68. else r <<= i;
  69. }
  70. lua_pushnumber(L, lua_uint2number(r));
  71. return 1;
  72. }
  73. static int b_rotate (lua_State *L) {
  74. b_uint r = getuintarg(L, 1);
  75. lua_Integer i = luaL_checkinteger(L, 2);
  76. i &= (NBITS - 1); /* i = i % NBITS */
  77. r = (r << i) | (r >> (NBITS - i));
  78. lua_pushnumber(L, lua_uint2number(r));
  79. return 1;
  80. }
  81. static const luaL_Reg bitlib[] = {
  82. {"band", b_and},
  83. {"btest", b_test},
  84. {"bor", b_or},
  85. {"bxor", b_xor},
  86. {"bnot", b_not},
  87. {"bshift", b_shift},
  88. {"brotate", b_rotate},
  89. {NULL, NULL}
  90. };
  91. LUALIB_API int luaopen_bit (lua_State *L) {
  92. luaL_register(L, LUA_BITLIBNAME, bitlib);
  93. return 1;
  94. }