?login_element?

Subversion Repositories NedoOS

Rev

Blame | Last modification | View Log | Download

  1. /*
  2. ** $Id: lbitlib.c,v 1.18.1.2 2013/07/09 18:01:41 roberto Exp $
  3. ** Standard library for bitwise operations
  4. ** See Copyright Notice in lua.h
  5. */
  6.  
  7. #define lbitlib_c
  8. #define LUA_LIB
  9.  
  10. #include "lua.h"
  11.  
  12. #include "lauxlib.h"
  13. #include "lualib.h"
  14.  
  15.  
  16. /* number of bits to consider in a number */
  17. #if !defined(LUA_NBITS)
  18. #define LUA_NBITS       32
  19. #endif
  20.  
  21.  
  22. #define ALLONES         (~(((~(lua_Unsigned)0) << (LUA_NBITS - 1)) << 1))
  23.  
  24. /* macro to trim extra bits */
  25. #define trim(x)         ((x) & ALLONES)
  26.  
  27.  
  28. /* builds a number with 'n' ones (1 <= n <= LUA_NBITS) */
  29. #define mask(n)         (~((ALLONES << 1) << ((n) - 1)))
  30.  
  31.  
  32. typedef lua_Unsigned b_uint;
  33.  
  34.  
  35.  
  36. static b_uint andaux (lua_State *L) {
  37.   int i, n = lua_gettop(L);
  38.   b_uint r = ~(b_uint)0;
  39.   for (i = 1; i <= n; i++)
  40.     r &= luaL_checkunsigned(L, i);
  41.   return trim(r);
  42. }
  43.  
  44.  
  45. static int b_and (lua_State *L) {
  46.   b_uint r = andaux(L);
  47.   lua_pushunsigned(L, r);
  48.   return 1;
  49. }
  50.  
  51.  
  52. static int b_test (lua_State *L) {
  53.   b_uint r = andaux(L);
  54.   lua_pushboolean(L, r != 0);
  55.   return 1;
  56. }
  57.  
  58.  
  59. static int b_or (lua_State *L) {
  60.   int i, n = lua_gettop(L);
  61.   b_uint r = 0;
  62.   for (i = 1; i <= n; i++)
  63.     r |= luaL_checkunsigned(L, i);
  64.   lua_pushunsigned(L, trim(r));
  65.   return 1;
  66. }
  67.  
  68.  
  69. static int b_xor (lua_State *L) {
  70.   int i, n = lua_gettop(L);
  71.   b_uint r = 0;
  72.   for (i = 1; i <= n; i++)
  73.     r ^= luaL_checkunsigned(L, i);
  74.   lua_pushunsigned(L, trim(r));
  75.   return 1;
  76. }
  77.  
  78.  
  79. static int b_not (lua_State *L) {
  80.   b_uint r = ~luaL_checkunsigned(L, 1);
  81.   lua_pushunsigned(L, trim(r));
  82.   return 1;
  83. }
  84.  
  85.  
  86. static int b_shift (lua_State *L, b_uint r, int i) {
  87.   if (i < 0) {  /* shift right? */
  88.     i = -i;
  89.     r = trim(r);
  90.     if (i >= LUA_NBITS) r = 0;
  91.     else r >>= i;
  92.   }
  93.   else {  /* shift left */
  94.     if (i >= LUA_NBITS) r = 0;
  95.     else r <<= i;
  96.     r = trim(r);
  97.   }
  98.   lua_pushunsigned(L, r);
  99.   return 1;
  100. }
  101.  
  102.  
  103. static int b_lshift (lua_State *L) {
  104.   return b_shift(L, luaL_checkunsigned(L, 1), luaL_checkint(L, 2));
  105. }
  106.  
  107.  
  108. static int b_rshift (lua_State *L) {
  109.   return b_shift(L, luaL_checkunsigned(L, 1), -luaL_checkint(L, 2));
  110. }
  111.  
  112.  
  113. static int b_arshift (lua_State *L) {
  114.   b_uint r = luaL_checkunsigned(L, 1);
  115.   int i = luaL_checkint(L, 2);
  116.   if (i < 0 || !(r & ((b_uint)1 << (LUA_NBITS - 1))))
  117.     return b_shift(L, r, -i);
  118.   else {  /* arithmetic shift for 'negative' number */
  119.     if (i >= LUA_NBITS) r = ALLONES;
  120.     else
  121.       r = trim((r >> i) | ~(~(b_uint)0 >> i));  /* add signal bit */
  122.     lua_pushunsigned(L, r);
  123.     return 1;
  124.   }
  125. }
  126.  
  127.  
  128. static int b_rot (lua_State *L, int i) {
  129.   b_uint r = luaL_checkunsigned(L, 1);
  130.   i &= (LUA_NBITS - 1);  /* i = i % NBITS */
  131.   r = trim(r);
  132.   if (i != 0)  /* avoid undefined shift of LUA_NBITS when i == 0 */
  133.     r = (r << i) | (r >> (LUA_NBITS - i));
  134.   lua_pushunsigned(L, trim(r));
  135.   return 1;
  136. }
  137.  
  138.  
  139. static int b_lrot (lua_State *L) {
  140.   return b_rot(L, luaL_checkint(L, 2));
  141. }
  142.  
  143.  
  144. static int b_rrot (lua_State *L) {
  145.   return b_rot(L, -luaL_checkint(L, 2));
  146. }
  147.  
  148.  
  149. /*
  150. ** get field and width arguments for field-manipulation functions,
  151. ** checking whether they are valid.
  152. ** ('luaL_error' called without 'return' to avoid later warnings about
  153. ** 'width' being used uninitialized.)
  154. */
  155. static int fieldargs (lua_State *L, int farg, int *width) {
  156.   int f = luaL_checkint(L, farg);
  157.   int w = luaL_optint(L, farg + 1, 1);
  158.   luaL_argcheck(L, 0 <= f, farg, "field cannot be negative");
  159.   luaL_argcheck(L, 0 < w, farg + 1, "width must be positive");
  160.   if (f + w > LUA_NBITS)
  161.     luaL_error(L, "trying to access non-existent bits");
  162.   *width = w;
  163.   return f;
  164. }
  165.  
  166.  
  167. static int b_extract (lua_State *L) {
  168.   int w;
  169.   b_uint r = luaL_checkunsigned(L, 1);
  170.   int f = fieldargs(L, 2, &w);
  171.   r = (r >> f) & mask(w);
  172.   lua_pushunsigned(L, r);
  173.   return 1;
  174. }
  175.  
  176.  
  177. static int b_replace (lua_State *L) {
  178.   int w;
  179.   b_uint r = luaL_checkunsigned(L, 1);
  180.   b_uint v = luaL_checkunsigned(L, 2);
  181.   int f = fieldargs(L, 3, &w);
  182.   int m = mask(w);
  183.   v &= m;  /* erase bits outside given width */
  184.   r = (r & ~(m << f)) | (v << f);
  185.   lua_pushunsigned(L, r);
  186.   return 1;
  187. }
  188.  
  189.  
  190. static const luaL_Reg bitlib[] = {
  191.   {"arshift", b_arshift},
  192.   {"band", b_and},
  193.   {"bnot", b_not},
  194.   {"bor", b_or},
  195.   {"bxor", b_xor},
  196.   {"btest", b_test},
  197.   {"extract", b_extract},
  198.   {"lrotate", b_lrot},
  199.   {"lshift", b_lshift},
  200.   {"replace", b_replace},
  201.   {"rrotate", b_rrot},
  202.   {"rshift", b_rshift},
  203.   {NULL, NULL}
  204. };
  205.  
  206.  
  207.  
  208. LUAMOD_API int luaopen_bit32 (lua_State *L) {
  209.   luaL_newlib(L, bitlib);
  210.   return 1;
  211. }
  212.  
  213.