diff options
| author | Philipp Janda <siffiejoe@gmx.net> | 2015-01-20 01:02:20 +0100 |
|---|---|---|
| committer | Philipp Janda <siffiejoe@gmx.net> | 2015-01-20 01:02:20 +0100 |
| commit | 489cd678823e0981ff2e4d2544b84094ed23c587 (patch) | |
| tree | 2855dbabb9205957434129aa1119cb526d2ae01b | |
| parent | f7f85b0826f7006b8dcc040111cd0ef8d42c2352 (diff) | |
| download | lua-compat-5.3-489cd678823e0981ff2e4d2544b84094ed23c587.tar.gz lua-compat-5.3-489cd678823e0981ff2e4d2544b84094ed23c587.tar.bz2 lua-compat-5.3-489cd678823e0981ff2e4d2544b84094ed23c587.zip | |
add lua_arith and lua_compare for Lua 5.1
| -rw-r--r-- | c-api/compat-5.3.c | 90 | ||||
| -rw-r--r-- | c-api/compat-5.3.h | 18 | ||||
| -rwxr-xr-x | tests/test.lua | 9 | ||||
| -rw-r--r-- | tests/testmod.c | 37 |
4 files changed, 152 insertions, 2 deletions
diff --git a/c-api/compat-5.3.c b/c-api/compat-5.3.c index e45c728..a539aed 100644 --- a/c-api/compat-5.3.c +++ b/c-api/compat-5.3.c | |||
| @@ -24,6 +24,96 @@ COMPAT53_API int lua_absindex (lua_State *L, int i) { | |||
| 24 | } | 24 | } |
| 25 | 25 | ||
| 26 | 26 | ||
| 27 | static const char compat53_arith_code[] = { | ||
| 28 | 'l', 'o', 'c', 'a', 'l', ' ', 'o', 'p', ',', 'a', ',', 'b', | ||
| 29 | '=', '.', '.', '.', '\n', | ||
| 30 | 'i', 'f', ' ', 'o', 'p', '=', '=', '0', ' ', | ||
| 31 | 't', 'h', 'e', 'n', '\n', | ||
| 32 | 'r', 'e', 't', 'u', 'r', 'n', ' ', 'a', '+', 'b', '\n', | ||
| 33 | 'e', 'l', 's', 'e', 'i', 'f', ' ', 'o', 'p', '=', '=', '1', ' ', | ||
| 34 | 't', 'h', 'e', 'n', '\n', | ||
| 35 | 'r', 'e', 't', 'u', 'r', 'n', ' ', 'a', '-', 'b', '\n', | ||
| 36 | 'e', 'l', 's', 'e', 'i', 'f', ' ', 'o', 'p', '=', '=', '2', ' ', | ||
| 37 | 't', 'h', 'e', 'n', '\n', | ||
| 38 | 'r', 'e', 't', 'u', 'r', 'n', ' ', 'a', '*', 'b', '\n', | ||
| 39 | 'e', 'l', 's', 'e', 'i', 'f', ' ', 'o', 'p', '=', '=', '3', ' ', | ||
| 40 | 't', 'h', 'e', 'n', '\n', | ||
| 41 | 'r', 'e', 't', 'u', 'r', 'n', ' ', 'a', '/', 'b', '\n', | ||
| 42 | 'e', 'l', 's', 'e', 'i', 'f', ' ', 'o', 'p', '=', '=', '4', ' ', | ||
| 43 | 't', 'h', 'e', 'n', '\n', | ||
| 44 | 'r', 'e', 't', 'u', 'r', 'n', ' ', 'a', '%', 'b', '\n', | ||
| 45 | 'e', 'l', 's', 'e', 'i', 'f', ' ', 'o', 'p', '=', '=', '5', ' ', | ||
| 46 | 't', 'h', 'e', 'n', '\n', | ||
| 47 | 'r', 'e', 't', 'u', 'r', 'n', ' ', 'a', '^', 'b', '\n', | ||
| 48 | 'e', 'l', 's', 'e', 'i', 'f', ' ', 'o', 'p', '=', '=', '6', ' ', | ||
| 49 | 't', 'h', 'e', 'n', '\n', | ||
| 50 | 'r', 'e', 't', 'u', 'r', 'n', ' ', '-', 'a', '\n', | ||
| 51 | 'e', 'n', 'd', '\n', '\0' | ||
| 52 | }; | ||
| 53 | |||
| 54 | COMPAT53_API void lua_arith (lua_State *L, int op) { | ||
| 55 | luaL_checkstack(L, 5, "not enough stack slots"); | ||
| 56 | if (op == LUA_OPUNM) | ||
| 57 | lua_pushvalue(L, -1); | ||
| 58 | lua_rawgetp(L, LUA_REGISTRYINDEX, (void*)compat53_arith_code); | ||
| 59 | if (lua_type(L, -1) != LUA_TFUNCTION) { | ||
| 60 | lua_pop(L, 1); | ||
| 61 | if (luaL_loadbuffer(L, compat53_arith_code, | ||
| 62 | sizeof(compat53_arith_code)-1, "=none")) | ||
| 63 | lua_error(L); | ||
| 64 | lua_pushvalue(L, -1); | ||
| 65 | lua_rawsetp(L, LUA_REGISTRYINDEX, (void*)compat53_arith_code); | ||
| 66 | } | ||
| 67 | lua_pushnumber(L, op); | ||
| 68 | lua_pushvalue(L, -4); | ||
| 69 | lua_pushvalue(L, -4); | ||
| 70 | lua_call(L, 3, 1); | ||
| 71 | lua_replace(L, -3); /* replace first operand */ | ||
| 72 | lua_pop(L, 1); /* pop second */ | ||
| 73 | } | ||
| 74 | |||
| 75 | |||
| 76 | static const char compat53_compare_code[] = { | ||
| 77 | 'l', 'o', 'c', 'a', 'l', ' ', 'o', 'p', ',', 'a', ',', 'b', | ||
| 78 | '=', '.', '.', '.', '\n', | ||
| 79 | 'i', 'f', ' ', 'o', 'p', '=', '=', '0', ' ', | ||
| 80 | 't', 'h', 'e', 'n', '\n', | ||
| 81 | 'r', 'e', 't', 'u', 'r', 'n', ' ', 'a', '=', '=', 'b', '\n', | ||
| 82 | 'e', 'l', 's', 'e', 'i', 'f', ' ', 'o', 'p', '=', '=', '1', ' ', | ||
| 83 | 't', 'h', 'e', 'n', '\n', | ||
| 84 | 'r', 'e', 't', 'u', 'r', 'n', ' ', 'a', '<', 'b', '\n', | ||
| 85 | 'e', 'l', 's', 'e', 'i', 'f', ' ', 'o', 'p', '=', '=', '2', ' ', | ||
| 86 | 't', 'h', 'e', 'n', '\n', | ||
| 87 | 'r', 'e', 't', 'u', 'r', 'n', ' ', 'a', '<', '=', 'b', '\n', | ||
| 88 | 'e', 'n', 'd', '\n', '\0' | ||
| 89 | }; | ||
| 90 | |||
| 91 | COMPAT53_API int lua_compare (lua_State *L, int idx1, int idx2, int op) { | ||
| 92 | int result = 0; | ||
| 93 | luaL_checkstack(L, 4, "not enough stack slots"); | ||
| 94 | idx1 = lua_absindex(L, idx1); | ||
| 95 | idx2 = lua_absindex(L, idx2); | ||
| 96 | lua_rawgetp(L, LUA_REGISTRYINDEX, (void*)compat53_compare_code); | ||
| 97 | if (lua_type(L, -1) != LUA_TFUNCTION) { | ||
| 98 | lua_pop(L, 1); | ||
| 99 | if (luaL_loadbuffer(L, compat53_compare_code, | ||
| 100 | sizeof(compat53_compare_code)-1, "=none")) | ||
| 101 | lua_error(L); | ||
| 102 | lua_pushvalue(L, -1); | ||
| 103 | lua_rawsetp(L, LUA_REGISTRYINDEX, (void*)compat53_compare_code); | ||
| 104 | } | ||
| 105 | lua_pushnumber(L, op); | ||
| 106 | lua_pushvalue(L, idx1); | ||
| 107 | lua_pushvalue(L, idx2); | ||
| 108 | lua_call(L, 3, 1); | ||
| 109 | if(lua_type(L, -1) != LUA_TBOOLEAN) | ||
| 110 | luaL_error(L, "invalid 'op' argument for lua_compare"); | ||
| 111 | result = lua_toboolean(L, -1); | ||
| 112 | lua_pop(L, 1); | ||
| 113 | return result; | ||
| 114 | } | ||
| 115 | |||
| 116 | |||
| 27 | COMPAT53_API void lua_copy (lua_State *L, int from, int to) { | 117 | COMPAT53_API void lua_copy (lua_State *L, int from, int to) { |
| 28 | int abs_to = lua_absindex(L, to); | 118 | int abs_to = lua_absindex(L, to); |
| 29 | luaL_checkstack(L, 1, "not enough stack slots"); | 119 | luaL_checkstack(L, 1, "not enough stack slots"); |
diff --git a/c-api/compat-5.3.h b/c-api/compat-5.3.h index b288126..3905a10 100644 --- a/c-api/compat-5.3.h +++ b/c-api/compat-5.3.h | |||
| @@ -40,8 +40,6 @@ | |||
| 40 | #if defined(LUA_VERSION_NUM) && LUA_VERSION_NUM == 501 | 40 | #if defined(LUA_VERSION_NUM) && LUA_VERSION_NUM == 501 |
| 41 | 41 | ||
| 42 | /* XXX not implemented: | 42 | /* XXX not implemented: |
| 43 | * lua_arith | ||
| 44 | * lua_compare | ||
| 45 | * lua_upvalueid | 43 | * lua_upvalueid |
| 46 | * lua_upvaluejoin | 44 | * lua_upvaluejoin |
| 47 | * lua_version | 45 | * lua_version |
| @@ -63,6 +61,16 @@ | |||
| 63 | #endif | 61 | #endif |
| 64 | 62 | ||
| 65 | #define LUA_OK 0 | 63 | #define LUA_OK 0 |
| 64 | #define LUA_OPADD 0 | ||
| 65 | #define LUA_OPSUB 1 | ||
| 66 | #define LUA_OPMUL 2 | ||
| 67 | #define LUA_OPDIV 3 | ||
| 68 | #define LUA_OPMOD 4 | ||
| 69 | #define LUA_OPPOW 5 | ||
| 70 | #define LUA_OPUNM 6 | ||
| 71 | #define LUA_OPEQ 0 | ||
| 72 | #define LUA_OPLT 1 | ||
| 73 | #define LUA_OPLE 2 | ||
| 66 | 74 | ||
| 67 | typedef struct luaL_Stream { | 75 | typedef struct luaL_Stream { |
| 68 | FILE *f; | 76 | FILE *f; |
| @@ -74,6 +82,12 @@ typedef size_t lua_Unsigned; | |||
| 74 | #define lua_absindex COMPAT53_CONCAT(COMPAT53_PREFIX, _absindex) | 82 | #define lua_absindex COMPAT53_CONCAT(COMPAT53_PREFIX, _absindex) |
| 75 | COMPAT53_API int lua_absindex (lua_State *L, int i); | 83 | COMPAT53_API int lua_absindex (lua_State *L, int i); |
| 76 | 84 | ||
| 85 | #define lua_arith COMPAT53_CONCAT(COMPAT53_PREFIX, _arith) | ||
| 86 | COMPAT53_API void lua_arith (lua_State *L, int op); | ||
| 87 | |||
| 88 | #define lua_compare COMPAT53_CONCAT(COMPAT53_PREFIX, _compare) | ||
| 89 | COMPAT53_API int lua_compare (lua_State *L, int idx1, int idx2, int op); | ||
| 90 | |||
| 77 | #define lua_copy COMPAT53_CONCAT(COMPAT53_PREFIX, _copy) | 91 | #define lua_copy COMPAT53_CONCAT(COMPAT53_PREFIX, _copy) |
| 78 | COMPAT53_API void lua_copy (lua_State *L, int from, int to); | 92 | COMPAT53_API void lua_copy (lua_State *L, int from, int to); |
| 79 | 93 | ||
diff --git a/tests/test.lua b/tests/test.lua index b59fd94..2b53b92 100755 --- a/tests/test.lua +++ b/tests/test.lua | |||
| @@ -314,6 +314,15 @@ ___'' | |||
| 314 | print(mod.absindex("hi", true)) | 314 | print(mod.absindex("hi", true)) |
| 315 | 315 | ||
| 316 | ___'' | 316 | ___'' |
| 317 | print(mod.arith(2, 1)) | ||
| 318 | print(mod.arith(3, 5)) | ||
| 319 | |||
| 320 | ___'' | ||
| 321 | print(mod.compare(1, 1)) | ||
| 322 | print(mod.compare(2, 1)) | ||
| 323 | print(mod.compare(1, 2)) | ||
| 324 | |||
| 325 | ___'' | ||
| 317 | print(mod.tolstring("string")) | 326 | print(mod.tolstring("string")) |
| 318 | local t = setmetatable({}, { | 327 | local t = setmetatable({}, { |
| 319 | __tostring = function(v) return "mytable" end | 328 | __tostring = function(v) return "mytable" end |
diff --git a/tests/testmod.c b/tests/testmod.c index a9c8e8d..2c6242b 100644 --- a/tests/testmod.c +++ b/tests/testmod.c | |||
| @@ -96,6 +96,41 @@ static int test_absindex (lua_State *L) { | |||
| 96 | return i; | 96 | return i; |
| 97 | } | 97 | } |
| 98 | 98 | ||
| 99 | static int test_arith (lua_State *L) { | ||
| 100 | lua_settop(L, 2); | ||
| 101 | lua_pushvalue(L, 1); | ||
| 102 | lua_pushvalue(L, 2); | ||
| 103 | lua_arith(L, LUA_OPADD); | ||
| 104 | lua_pushvalue(L, 1); | ||
| 105 | lua_pushvalue(L, 2); | ||
| 106 | lua_arith(L, LUA_OPSUB); | ||
| 107 | lua_pushvalue(L, 1); | ||
| 108 | lua_pushvalue(L, 2); | ||
| 109 | lua_arith(L, LUA_OPMUL); | ||
| 110 | lua_pushvalue(L, 1); | ||
| 111 | lua_pushvalue(L, 2); | ||
| 112 | lua_arith(L, LUA_OPDIV); | ||
| 113 | lua_pushvalue(L, 1); | ||
| 114 | lua_pushvalue(L, 2); | ||
| 115 | lua_arith(L, LUA_OPMOD); | ||
| 116 | lua_pushvalue(L, 1); | ||
| 117 | lua_pushvalue(L, 2); | ||
| 118 | lua_arith(L, LUA_OPPOW); | ||
| 119 | lua_pushvalue(L, 1); | ||
| 120 | lua_arith(L, LUA_OPUNM); | ||
| 121 | return lua_gettop(L)-2; | ||
| 122 | } | ||
| 123 | |||
| 124 | static int test_compare (lua_State *L) { | ||
| 125 | luaL_checknumber(L, 1); | ||
| 126 | luaL_checknumber(L, 2); | ||
| 127 | lua_settop(L, 2); | ||
| 128 | lua_pushboolean(L, lua_compare(L, 1, 2, LUA_OPEQ)); | ||
| 129 | lua_pushboolean(L, lua_compare(L, 1, 2, LUA_OPLT)); | ||
| 130 | lua_pushboolean(L, lua_compare(L, 1, 2, LUA_OPLE)); | ||
| 131 | return 3; | ||
| 132 | } | ||
| 133 | |||
| 99 | static int test_globals (lua_State *L) { | 134 | static int test_globals (lua_State *L) { |
| 100 | lua_pushglobaltable(L); | 135 | lua_pushglobaltable(L); |
| 101 | return 1; | 136 | return 1; |
| @@ -215,6 +250,8 @@ static const luaL_Reg funcs[] = { | |||
| 215 | { "requiref", test_requiref }, | 250 | { "requiref", test_requiref }, |
| 216 | { "getseti", test_getseti }, | 251 | { "getseti", test_getseti }, |
| 217 | { "newproxy", test_newproxy }, | 252 | { "newproxy", test_newproxy }, |
| 253 | { "arith", test_arith }, | ||
| 254 | { "compare", test_compare }, | ||
| 218 | { "tonumber", test_tonumber }, | 255 | { "tonumber", test_tonumber }, |
| 219 | { "tointeger", test_tointeger }, | 256 | { "tointeger", test_tointeger }, |
| 220 | { "len", test_len }, | 257 | { "len", test_len }, |
