diff options
author | Philipp Janda <siffiejoe@gmx.net> | 2020-07-09 01:24:17 +0200 |
---|---|---|
committer | Philipp Janda <siffiejoe@gmx.net> | 2020-07-09 01:24:17 +0200 |
commit | 7e2b0b5e5f55cac22fbd9237bf1c354df134802c (patch) | |
tree | 3cf37119c740ba76b874d5e6badd9e5e00cf37a7 | |
parent | 931652ad9ef34c99e53007de9f92bfd5a397a219 (diff) | |
download | lua-compat-5.3-7e2b0b5e5f55cac22fbd9237bf1c354df134802c.tar.gz lua-compat-5.3-7e2b0b5e5f55cac22fbd9237bf1c354df134802c.tar.bz2 lua-compat-5.3-7e2b0b5e5f55cac22fbd9237bf1c354df134802c.zip |
Add bit32 library
-rw-r--r-- | lbitlib.c | 233 | ||||
-rw-r--r-- | rockspecs/bit32-5.3.5-1.rockspec | 28 | ||||
-rw-r--r-- | rockspecs/bit32-scm-1.rockspec | 28 | ||||
-rwxr-xr-x | tests/test-bit32.lua | 9 |
4 files changed, 298 insertions, 0 deletions
diff --git a/lbitlib.c b/lbitlib.c new file mode 100644 index 0000000..4786c0d --- /dev/null +++ b/lbitlib.c | |||
@@ -0,0 +1,233 @@ | |||
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 /* } */ | ||
diff --git a/rockspecs/bit32-5.3.5-1.rockspec b/rockspecs/bit32-5.3.5-1.rockspec new file mode 100644 index 0000000..be2f5a7 --- /dev/null +++ b/rockspecs/bit32-5.3.5-1.rockspec | |||
@@ -0,0 +1,28 @@ | |||
1 | package = "bit32" | ||
2 | version = "5.3.5-1" | ||
3 | source = { | ||
4 | url = "git://github.com/keplerproject/lua-compat-5.3/archive/v0.9.zip", | ||
5 | dir = "lua-compat-5.3-0.9", | ||
6 | } | ||
7 | description = { | ||
8 | summary = "Lua 5.2 bit manipulation library", | ||
9 | detailed = [[ | ||
10 | bit32 is the native Lua 5.2 bit manipulation library, in the version | ||
11 | from Lua 5.3; it is compatible with Lua 5.1, 5.2 and 5.3. | ||
12 | ]], | ||
13 | homepage = "http://www.lua.org/manual/5.2/manual.html#6.7", | ||
14 | license = "MIT" | ||
15 | } | ||
16 | dependencies = { | ||
17 | "lua >= 5.1, < 5.5" | ||
18 | } | ||
19 | build = { | ||
20 | type = "builtin", | ||
21 | modules = { | ||
22 | bit32 = { | ||
23 | sources = { "lbitlib.c" }, | ||
24 | defines = { "LUA_COMPAT_BITLIB" }, | ||
25 | incdirs = { "c-api" }, | ||
26 | } | ||
27 | } | ||
28 | } | ||
diff --git a/rockspecs/bit32-scm-1.rockspec b/rockspecs/bit32-scm-1.rockspec new file mode 100644 index 0000000..cce77de --- /dev/null +++ b/rockspecs/bit32-scm-1.rockspec | |||
@@ -0,0 +1,28 @@ | |||
1 | package = "bit32" | ||
2 | version = "scm-1" | ||
3 | source = { | ||
4 | url = "https://github.com/keplerproject/lua-compat-5.3/archive/master.zip", | ||
5 | branch = "lua-compat-5.3-master", | ||
6 | } | ||
7 | description = { | ||
8 | summary = "Lua 5.2 bit manipulation library", | ||
9 | detailed = [[ | ||
10 | bit32 is the native Lua 5.2 bit manipulation library, in the version | ||
11 | from Lua 5.3; it is compatible with Lua 5.1, 5.2 and 5.3. | ||
12 | ]], | ||
13 | homepage = "http://www.lua.org/manual/5.2/manual.html#6.7", | ||
14 | license = "MIT" | ||
15 | } | ||
16 | dependencies = { | ||
17 | "lua >= 5.1, < 5.5" | ||
18 | } | ||
19 | build = { | ||
20 | type = "builtin", | ||
21 | modules = { | ||
22 | bit32 = { | ||
23 | sources = { "lbitlib.c" }, | ||
24 | defines = { "LUA_COMPAT_BITLIB" }, | ||
25 | incdirs = { "c-api" }, | ||
26 | } | ||
27 | } | ||
28 | } | ||
diff --git a/tests/test-bit32.lua b/tests/test-bit32.lua new file mode 100755 index 0000000..cc91e52 --- /dev/null +++ b/tests/test-bit32.lua | |||
@@ -0,0 +1,9 @@ | |||
1 | #!/usr/bin/env lua | ||
2 | |||
3 | local bit32 = require("bit32") | ||
4 | |||
5 | |||
6 | assert(bit32.bnot(0) == 2^32-1) | ||
7 | assert(bit32.band(1, 3, 5) == 1) | ||
8 | assert(bit32.bor(1, 3, 5) == 7) | ||
9 | |||