?login_element?

Subversion Repositories NedoOS

Rev

Blame | Last modification | View Log | Download

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