aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorRoberto Ierusalimschy <roberto@inf.puc-rio.br>2010-11-29 13:19:28 -0200
committerRoberto Ierusalimschy <roberto@inf.puc-rio.br>2010-11-29 13:19:28 -0200
commit7ca1bd639fe0fcff7bcb0c3db34e35a6cab144e1 (patch)
tree1a955a1935da1742c471becfb34da8c27a55d852
parent9b7a12c46d85666e0e60efd79b39495589e497e8 (diff)
downloadlua-7ca1bd639fe0fcff7bcb0c3db34e35a6cab144e1.tar.gz
lua-7ca1bd639fe0fcff7bcb0c3db34e35a6cab144e1.tar.bz2
lua-7ca1bd639fe0fcff7bcb0c3db34e35a6cab144e1.zip
new functions 'extract' and 'replace'
-rw-r--r--lbitlib.c69
1 files changed, 56 insertions, 13 deletions
diff --git a/lbitlib.c b/lbitlib.c
index e3ce2f3c..3e86bab1 100644
--- a/lbitlib.c
+++ b/lbitlib.c
@@ -1,5 +1,5 @@
1/* 1/*
2** $Id: lbitlib.c,v 1.12 2010/11/22 16:39:20 roberto Exp roberto $ 2** $Id: lbitlib.c,v 1.13 2010/11/22 18:06:33 roberto Exp roberto $
3** Standard library for bitwise operations 3** Standard library for bitwise operations
4** See Copyright Notice in lua.h 4** See Copyright Notice in lua.h
5*/ 5*/
@@ -18,21 +18,23 @@
18 18
19#define ALLONES (~(((~(lua_Unsigned)0) << (NBITS - 1)) << 1)) 19#define ALLONES (~(((~(lua_Unsigned)0) << (NBITS - 1)) << 1))
20 20
21/* mask to trim extra bits */ 21/* macro to trim extra bits */
22#define trim(x) ((x) & ALLONES) 22#define trim(x) ((x) & ALLONES)
23 23
24 24
25typedef lua_Unsigned b_uint; 25/* builds a number with 'n' ones (1 <= n <= NBITS) */
26#define mask(n) (~((ALLONES << 1) << ((n) - 1)))
27
26 28
29typedef lua_Unsigned b_uint;
27 30
28#define getuintarg(L,arg) luaL_checkunsigned(L,arg)
29 31
30 32
31static b_uint andaux (lua_State *L) { 33static b_uint andaux (lua_State *L) {
32 int i, n = lua_gettop(L); 34 int i, n = lua_gettop(L);
33 b_uint r = ~(b_uint)0; 35 b_uint r = ~(b_uint)0;
34 for (i = 1; i <= n; i++) 36 for (i = 1; i <= n; i++)
35 r &= getuintarg(L, i); 37 r &= luaL_checkunsigned(L, i);
36 return trim(r); 38 return trim(r);
37} 39}
38 40
@@ -55,7 +57,7 @@ static int b_or (lua_State *L) {
55 int i, n = lua_gettop(L); 57 int i, n = lua_gettop(L);
56 b_uint r = 0; 58 b_uint r = 0;
57 for (i = 1; i <= n; i++) 59 for (i = 1; i <= n; i++)
58 r |= getuintarg(L, i); 60 r |= luaL_checkunsigned(L, i);
59 lua_pushunsigned(L, trim(r)); 61 lua_pushunsigned(L, trim(r));
60 return 1; 62 return 1;
61} 63}
@@ -65,14 +67,14 @@ static int b_xor (lua_State *L) {
65 int i, n = lua_gettop(L); 67 int i, n = lua_gettop(L);
66 b_uint r = 0; 68 b_uint r = 0;
67 for (i = 1; i <= n; i++) 69 for (i = 1; i <= n; i++)
68 r ^= getuintarg(L, i); 70 r ^= luaL_checkunsigned(L, i);
69 lua_pushunsigned(L, trim(r)); 71 lua_pushunsigned(L, trim(r));
70 return 1; 72 return 1;
71} 73}
72 74
73 75
74static int b_not (lua_State *L) { 76static int b_not (lua_State *L) {
75 b_uint r = ~getuintarg(L, 1); 77 b_uint r = ~luaL_checkunsigned(L, 1);
76 lua_pushunsigned(L, trim(r)); 78 lua_pushunsigned(L, trim(r));
77 return 1; 79 return 1;
78} 80}
@@ -96,17 +98,17 @@ static int b_shift (lua_State *L, b_uint r, int i) {
96 98
97 99
98static int b_lshift (lua_State *L) { 100static int b_lshift (lua_State *L) {
99 return b_shift(L, getuintarg(L, 1), luaL_checkint(L, 2)); 101 return b_shift(L, luaL_checkunsigned(L, 1), luaL_checkint(L, 2));
100} 102}
101 103
102 104
103static int b_rshift (lua_State *L) { 105static int b_rshift (lua_State *L) {
104 return b_shift(L, getuintarg(L, 1), -luaL_checkint(L, 2)); 106 return b_shift(L, luaL_checkunsigned(L, 1), -luaL_checkint(L, 2));
105} 107}
106 108
107 109
108static int b_arshift (lua_State *L) { 110static int b_arshift (lua_State *L) {
109 b_uint r = getuintarg(L, 1); 111 b_uint r = luaL_checkunsigned(L, 1);
110 int i = luaL_checkint(L, 2); 112 int i = luaL_checkint(L, 2);
111 if (i < 0 || !(r & ((b_uint)1 << (NBITS - 1)))) 113 if (i < 0 || !(r & ((b_uint)1 << (NBITS - 1))))
112 return b_shift(L, r, -i); 114 return b_shift(L, r, -i);
@@ -121,7 +123,7 @@ static int b_arshift (lua_State *L) {
121 123
122 124
123static int b_rot (lua_State *L, int i) { 125static int b_rot (lua_State *L, int i) {
124 b_uint r = getuintarg(L, 1); 126 b_uint r = luaL_checkunsigned(L, 1);
125 i &= (NBITS - 1); /* i = i % NBITS */ 127 i &= (NBITS - 1); /* i = i % NBITS */
126 r = trim(r); 128 r = trim(r);
127 r = (r << i) | (r >> (NBITS - i)); 129 r = (r << i) | (r >> (NBITS - i));
@@ -140,17 +142,58 @@ static int b_rrot (lua_State *L) {
140} 142}
141 143
142 144
145/*
146** get field and width arguments for field-manipulation functions,
147** checking whether they are valid
148*/
149static int fieldargs (lua_State *L, int farg, int *width) {
150 int f = luaL_checkint(L, farg);
151 int w = luaL_optint(L, farg + 1, 1);
152 luaL_argcheck(L, 0 <= f, farg, "field cannot be netative");
153 luaL_argcheck(L, 0 < w, farg + 1, "width must be positive");
154 if (f + w > NBITS)
155 luaL_error(L, "trying to access non-existent bits");
156 *width = w;
157 return f;
158}
159
160
161static int b_extract (lua_State *L) {
162 int w;
163 b_uint r = luaL_checkunsigned(L, 1);
164 int f = fieldargs(L, 2, &w);
165 r = (r >> f) & mask(w);
166 lua_pushunsigned(L, r);
167 return 1;
168}
169
170
171static int b_replace (lua_State *L) {
172 int w;
173 b_uint r = luaL_checkunsigned(L, 1);
174 b_uint v = luaL_checkunsigned(L, 2);
175 int f = fieldargs(L, 3, &w);
176 int m = mask(w);
177 v &= m; /* erase bits outside given width */
178 r = (r & ~(m << f)) | (v << f);
179 lua_pushunsigned(L, r);
180 return 1;
181}
182
183
143static const luaL_Reg bitlib[] = { 184static const luaL_Reg bitlib[] = {
144 {"arshift", b_arshift}, 185 {"arshift", b_arshift},
145 {"band", b_and}, 186 {"band", b_and},
146 {"bnot", b_not}, 187 {"bnot", b_not},
147 {"bor", b_or}, 188 {"bor", b_or},
148 {"bxor", b_xor}, 189 {"bxor", b_xor},
190 {"btest", b_test},
191 {"extract", b_extract},
149 {"lrotate", b_lrot}, 192 {"lrotate", b_lrot},
150 {"lshift", b_lshift}, 193 {"lshift", b_lshift},
194 {"replace", b_replace},
151 {"rrotate", b_rrot}, 195 {"rrotate", b_rrot},
152 {"rshift", b_rshift}, 196 {"rshift", b_rshift},
153 {"btest", b_test},
154 {NULL, NULL} 197 {NULL, NULL}
155}; 198};
156 199