aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorRoberto Ierusalimschy <roberto@inf.puc-rio.br>2009-07-01 13:17:08 -0300
committerRoberto Ierusalimschy <roberto@inf.puc-rio.br>2009-07-01 13:17:08 -0300
commit88564c3aec8122ce20bd257e01d4ab32c9663051 (patch)
treeee61eca3aab50e847245210764baee132cd628cb
parent3abe3da9fb9baf24e4e9e1cfb0212cce00d70fee (diff)
downloadlua-88564c3aec8122ce20bd257e01d4ab32c9663051.tar.gz
lua-88564c3aec8122ce20bd257e01d4ab32c9663051.tar.bz2
lua-88564c3aec8122ce20bd257e01d4ab32c9663051.zip
Standard library for bitwise operations
-rw-r--r--lbitlib.c123
1 files changed, 123 insertions, 0 deletions
diff --git a/lbitlib.c b/lbitlib.c
new file mode 100644
index 00000000..4f715288
--- /dev/null
+++ b/lbitlib.c
@@ -0,0 +1,123 @@
1/*
2** $Id: $
3** Standard library for bitwise operations
4** See Copyright Notice in lua.h
5*/
6
7#include "lua.h"
8
9#include "lauxlib.h"
10#include "lualib.h"
11
12
13/* number of bits considered when shifting/rotating (must be a power of 2) */
14#define NBITS 32
15
16
17typedef LUA_INT32 b_int;
18typedef unsigned LUA_INT32 b_uint;
19
20
21static b_uint getuintarg (lua_State *L, int arg) {
22 b_uint r;
23 lua_Number x = lua_tonumber(L, arg);
24 if (x == 0) luaL_checktype(L, arg, LUA_TNUMBER);
25 lua_number2uint(r, x);
26 return r;
27}
28
29
30static b_uint andaux (lua_State *L) {
31 int i, n = lua_gettop(L);
32 b_uint r = ~(b_uint)0;
33 for (i = 1; i <= n; i++)
34 r &= getuintarg(L, i);
35 return r;
36}
37
38
39static int b_and (lua_State *L) {
40 b_uint r = andaux(L);
41 lua_pushnumber(L, lua_uint2number(r));
42 return 1;
43}
44
45
46static int b_test (lua_State *L) {
47 b_uint r = andaux(L);
48 lua_pushboolean(L, r != 0);
49 return 1;
50}
51
52
53static int b_or (lua_State *L) {
54 int i, n = lua_gettop(L);
55 b_uint r = 0;
56 for (i = 1; i <= n; i++)
57 r |= getuintarg(L, i);
58 lua_pushnumber(L, lua_uint2number(r));
59 return 1;
60}
61
62
63static int b_xor (lua_State *L) {
64 int i, n = lua_gettop(L);
65 b_uint r = 0;
66 for (i = 1; i <= n; i++)
67 r ^= getuintarg(L, i);
68 lua_pushnumber(L, lua_uint2number(r));
69 return 1;
70}
71
72
73static int b_not (lua_State *L) {
74 b_uint r = ~getuintarg(L, 1);
75 lua_pushnumber(L, lua_uint2number(r));
76 return 1;
77}
78
79
80static int b_shift (lua_State *L) {
81 b_uint r = getuintarg(L, 1);
82 lua_Integer i = luaL_checkinteger(L, 2);
83 if (i < 0) { /* shift right? */
84 i = -i;
85 if (i >= NBITS) r = 0;
86 else r >>= i;
87 }
88 else { /* shift left */
89 if (i >= NBITS) r = 0;
90 else r <<= i;
91 }
92 lua_pushnumber(L, lua_uint2number(r));
93 return 1;
94}
95
96
97static int b_rotate (lua_State *L) {
98 b_uint r = getuintarg(L, 1);
99 lua_Integer i = luaL_checkinteger(L, 2);
100 i &= (NBITS - 1); /* i = i % NBITS */
101 r = (r << i) | (r >> (NBITS - i));
102 lua_pushnumber(L, lua_uint2number(r));
103 return 1;
104}
105
106
107static const luaL_Reg bitlib[] = {
108 {"band", b_and},
109 {"btest", b_test},
110 {"bor", b_or},
111 {"bxor", b_xor},
112 {"bnot", b_not},
113 {"bshift", b_shift},
114 {"brotate", b_rotate},
115 {NULL, NULL}
116};
117
118
119
120LUALIB_API int luaopen_bit (lua_State *L) {
121 luaL_register(L, LUA_BITLIBNAME, bitlib);
122 return 1;
123}