summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMaurus Cuelenaere <mcuelenaere@gmail.com>2009-06-01 22:02:18 +0000
committerMaurus Cuelenaere <mcuelenaere@gmail.com>2009-06-01 22:02:18 +0000
commit82eea9ed69886a4eaf41a1124b292635ca60fe9a (patch)
treedb6bb8849b433a8440770015de490327cbfb4195
parentc1d27d105c3333b5df67c97d88885efa2a49bc9a (diff)
downloadrockbox-82eea9ed69886a4eaf41a1124b292635ca60fe9a.tar.gz
rockbox-82eea9ed69886a4eaf41a1124b292635ca60fe9a.zip
Lua: add bitlib (makes bitwise operators possible)
git-svn-id: svn://svn.rockbox.org/rockbox/trunk@21164 a1c6a512-1295-4272-9138-f99709370657
-rw-r--r--apps/plugins/lua/SOURCES1
-rw-r--r--apps/plugins/lua/lbitlib.c125
-rw-r--r--apps/plugins/lua/lualib.h2
-rw-r--r--apps/plugins/lua/rocklua.c1
4 files changed, 129 insertions, 0 deletions
diff --git a/apps/plugins/lua/SOURCES b/apps/plugins/lua/SOURCES
index 058b991417..b443ce8437 100644
--- a/apps/plugins/lua/SOURCES
+++ b/apps/plugins/lua/SOURCES
@@ -1,6 +1,7 @@
1lauxlib.c 1lauxlib.c
2lapi.c 2lapi.c
3lbaselib.c 3lbaselib.c
4lbitlib.c
4lcode.c 5lcode.c
5ldebug.c 6ldebug.c
6ldo.c 7ldo.c
diff --git a/apps/plugins/lua/lbitlib.c b/apps/plugins/lua/lbitlib.c
new file mode 100644
index 0000000000..f7e4619377
--- /dev/null
+++ b/apps/plugins/lua/lbitlib.c
@@ -0,0 +1,125 @@
1/* Bitwise operations library */
2/* (c) Reuben Thomas 2000-2008 */
3/* bitlib is copyright Reuben Thomas 2000-2008, and is released under the MIT
4 license, like Lua (see http://www.lua.org/copyright.html; it's
5 basically the same as the BSD license). There is no warranty. */
6
7#include "config.h"
8
9#include <lua.h>
10#include <lauxlib.h>
11#include <limits.h>
12
13
14/* FIXME: Assume lua_Integer is ptrdiff_t */
15#define LUA_INTEGER_MAX INTPTR_MAX
16#define LUA_INTEGER_MIN INTPTR_MIN
17
18/* FIXME: Assume size_t is an unsigned lua_Integer */
19typedef size_t lua_UInteger;
20#define LUA_UINTEGER_MAX UINT_MAX
21
22
23/* Bit type size and limits */
24
25#define BIT_BITS (CHAR_BIT * sizeof(lua_Integer))
26
27/* This code may give warnings if BITLIB_FLOAT_* are too big to fit in
28 long, but that doesn't matter since in that case they won't be
29 used. */
30#define BIT_MAX (LUA_INTEGER_MAX)
31
32#define BIT_MIN (LUA_INTEGER_MIN)
33
34#define BIT_UMAX (LUA_UINTEGER_MAX)
35
36
37/* Define TOBIT to get a bit value */
38#ifdef BUILTIN_CAST
39#define
40#define TOBIT(L, n, res) \
41 ((void)(res), luaL_checkinteger((L), (n)))
42#else
43
44#define TOBIT(L, n, res) \
45 ((lua_Integer)(((res) = luaL_checknumber(L, (n)) % BIT_UMAX), \
46 (res) > BIT_MAX ? ((res) -= BIT_UMAX, (res) -= 1) : \
47 ((res) < BIT_MIN ? ((res) += BIT_UMAX, (res) += 1) : (res))))
48#endif
49
50
51#define BIT_TRUNCATE(i) \
52 ((i) & BIT_UMAX)
53
54
55/* Operations
56
57 The macros MONADIC and VARIADIC only deal with bitwise operations.
58
59 LOGICAL_SHIFT truncates its left-hand operand before shifting so
60 that any extra bits at the most-significant end are not shifted
61 into the result.
62
63 ARITHMETIC_SHIFT does not truncate its left-hand operand, so that
64 the sign bits are not removed and right shift work properly.
65 */
66
67#define MONADIC(name, op) \
68 static int bit_ ## name(lua_State *L) { \
69 lua_Number f; \
70 lua_pushinteger(L, BIT_TRUNCATE(op TOBIT(L, 1, f))); \
71 return 1; \
72 }
73
74#define VARIADIC(name, op) \
75 static int bit_ ## name(lua_State *L) { \
76 lua_Number f; \
77 int n = lua_gettop(L), i; \
78 lua_Integer w = TOBIT(L, 1, f); \
79 for (i = 2; i <= n; i++) \
80 w op TOBIT(L, i, f); \
81 lua_pushinteger(L, BIT_TRUNCATE(w)); \
82 return 1; \
83 }
84
85#define LOGICAL_SHIFT(name, op) \
86 static int bit_ ## name(lua_State *L) { \
87 lua_Number f; \
88 lua_pushinteger(L, BIT_TRUNCATE(BIT_TRUNCATE((lua_UInteger)TOBIT(L, 1, f)) op \
89 (unsigned)luaL_checknumber(L, 2))); \
90 return 1; \
91 }
92
93#define ARITHMETIC_SHIFT(name, op) \
94 static int bit_ ## name(lua_State *L) { \
95 lua_Number f; \
96 lua_pushinteger(L, BIT_TRUNCATE((lua_Integer)TOBIT(L, 1, f) op \
97 (unsigned)luaL_checknumber(L, 2))); \
98 return 1; \
99 }
100
101MONADIC(bnot, ~)
102VARIADIC(band, &=)
103VARIADIC(bor, |=)
104VARIADIC(bxor, ^=)
105ARITHMETIC_SHIFT(lshift, <<)
106LOGICAL_SHIFT(rshift, >>)
107ARITHMETIC_SHIFT(arshift, >>)
108
109static const struct luaL_reg bitlib[] = {
110 {"bnot", bit_bnot},
111 {"band", bit_band},
112 {"bor", bit_bor},
113 {"bxor", bit_bxor},
114 {"lshift", bit_lshift},
115 {"rshift", bit_rshift},
116 {"arshift", bit_arshift},
117 {NULL, NULL}
118};
119
120LUALIB_API int luaopen_bit (lua_State *L) {
121 luaL_register(L, "bit", bitlib);
122 lua_pushnumber(L, BIT_BITS);
123 lua_setfield(L, -2, "bits");
124 return 1;
125}
diff --git a/apps/plugins/lua/lualib.h b/apps/plugins/lua/lualib.h
index 33d4e314c2..d4f69fc4af 100644
--- a/apps/plugins/lua/lualib.h
+++ b/apps/plugins/lua/lualib.h
@@ -39,6 +39,8 @@ LUALIB_API int (luaopen_debug) (lua_State *L);
39#define LUA_LOADLIBNAME "package" 39#define LUA_LOADLIBNAME "package"
40LUALIB_API int (luaopen_package) (lua_State *L); 40LUALIB_API int (luaopen_package) (lua_State *L);
41 41
42#define LUA_BITLIBNAME "bit"
43LUALIB_API int (luaopen_bit) (lua_State *L);
42 44
43/* open all previous libraries */ 45/* open all previous libraries */
44LUALIB_API void (luaL_openlibs) (lua_State *L); 46LUALIB_API void (luaL_openlibs) (lua_State *L);
diff --git a/apps/plugins/lua/rocklua.c b/apps/plugins/lua/rocklua.c
index 1162c026d1..98ffea8123 100644
--- a/apps/plugins/lua/rocklua.c
+++ b/apps/plugins/lua/rocklua.c
@@ -35,6 +35,7 @@ static const luaL_Reg lualibs[] = {
35 {LUA_STRLIBNAME, luaopen_string}, 35 {LUA_STRLIBNAME, luaopen_string},
36 {LUA_OSLIBNAME, luaopen_os}, 36 {LUA_OSLIBNAME, luaopen_os},
37 {LUA_ROCKLIBNAME, luaopen_rock}, 37 {LUA_ROCKLIBNAME, luaopen_rock},
38 {LUA_BITLIBNAME, luaopen_bit},
38 {NULL, NULL} 39 {NULL, NULL}
39}; 40};
40 41