aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--README.md2
-rw-r--r--src/lbaselib.js7
-rw-r--r--tests/lbaselib.js91
3 files changed, 98 insertions, 2 deletions
diff --git a/README.md b/README.md
index 4781092..f67e193 100644
--- a/README.md
+++ b/README.md
@@ -213,12 +213,12 @@
- [x] xpcall
- [x] collectgarbage (unavailable)
- [x] ipairs
+ - [x] pairs
- [x] select
- [x] tonumber
- [x] assert
- [x] rawlen
- [x] next
- - [ ] pairs
- [ ] dofile
- [ ] loadfile
- [ ] load
diff --git a/src/lbaselib.js b/src/lbaselib.js
index f405a7d..012f5c3 100644
--- a/src/lbaselib.js
+++ b/src/lbaselib.js
@@ -98,7 +98,7 @@ const luaB_type = function(L) {
const pairsmeta = function(L, method, iszero, iter) {
lauxlib.luaL_checkany(L, 1);
- if (lauxlib.luaL_getmetafield(L, 1, method).ttisnil()) { /* no metamethod? */
+ if (lauxlib.luaL_getmetafield(L, 1, method) === CT.LUA_TNIL) { /* no metamethod? */
lapi.lua_pushcfunction(L, iter); /* will return generator, */
lapi.lua_pushvalue(L, 1); /* state, */
if (iszero) lapi.lua_pushinteger(L, 0); /* and initial value */
@@ -121,6 +121,10 @@ const luaB_next = function(L) {
}
};
+const luaB_pairs = function(L) {
+ return pairsmeta(L, "__pairs", 0, luaB_next);
+};
+
/*
** Traversal function for 'ipairs'
*/
@@ -256,6 +260,7 @@ const base_funcs = {
"tonumber": luaB_tonumber,
"getmetatable": luaB_getmetatable,
"next": luaB_next,
+ "pairs": luaB_pairs,
"ipairs": luaB_ipairs,
"select": luaB_select,
"setmetatable": luaB_setmetatable,
diff --git a/tests/lbaselib.js b/tests/lbaselib.js
index d2f0e0e..be5cdad 100644
--- a/tests/lbaselib.js
+++ b/tests/lbaselib.js
@@ -593,4 +593,95 @@ test('next', function (t) {
10,
"Correct element(s) on the stack"
);
+});
+
+
+test('pairs', function (t) {
+ let luaCode = `
+ local total = 0
+ local t = {
+ 1,
+ two = 2,
+ 3,
+ four = 4
+ }
+
+ for k,v in pairs(t) do
+ total = total + v
+ end
+
+ return total
+ `, L;
+
+ t.plan(2);
+
+ t.doesNotThrow(function () {
+
+ let bc = toByteCode(luaCode).dataView;
+
+ L = lauxlib.luaL_newstate();
+
+ linit.luaL_openlibs(L);
+
+ lapi.lua_load(L, bc, "test-pairs");
+
+ lapi.lua_call(L, 0, -1);
+
+ }, "JS Lua program ran without error");
+
+ t.strictEqual(
+ lapi.lua_tonumber(L, -1),
+ 10,
+ "Correct element(s) on the stack"
+ );
+});
+
+
+test('pairs with __pairs', function (t) {
+ let luaCode = `
+ local total = 0
+
+ local mt = {
+ __pairs = function(t)
+ return next, {5, 6, 7, 8}, nil
+ end
+ }
+
+ local t = {
+ 1,
+ two = 2,
+ 3,
+ four = 4
+ }
+
+ setmetatable(t, mt)
+
+ for k,v in pairs(t) do
+ total = total + v
+ end
+
+ return total
+ `, L;
+
+ t.plan(2);
+
+ t.doesNotThrow(function () {
+
+ let bc = toByteCode(luaCode).dataView;
+
+ L = lauxlib.luaL_newstate();
+
+ linit.luaL_openlibs(L);
+
+ lapi.lua_load(L, bc, "test-pairs");
+
+ lapi.lua_call(L, 0, -1);
+
+ }, "JS Lua program ran without error");
+
+ t.strictEqual(
+ lapi.lua_tonumber(L, -1),
+ 26,
+ "Correct element(s) on the stack"
+ );
}); \ No newline at end of file