From 7c459409b078e38da07e2570a77945fdc0f55c2c Mon Sep 17 00:00:00 2001 From: Benoit Giannangeli Date: Wed, 22 Feb 2017 21:40:11 +0100 Subject: pairs --- README.md | 2 +- src/lbaselib.js | 7 ++++- tests/lbaselib.js | 91 +++++++++++++++++++++++++++++++++++++++++++++++++++++++ 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 -- cgit v1.2.3-70-g09d2