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