diff options
| -rw-r--r-- | README.md | 8 | ||||
| -rw-r--r-- | src/liolib.js | 33 | ||||
| -rw-r--r-- | src/loadlib.js | 44 | 
3 files changed, 69 insertions, 16 deletions
@@ -29,6 +29,7 @@      - [x] Package      - [ ] io          - [x] `file:__tostring()` +        - [x] `file:flush()`          - [x] `file:write()`          - [x] `io.close()`          - [x] `io.stderr` @@ -36,15 +37,14 @@          - [x] `io.stdout`          - [x] `io.type()`          - [x] `io.write()` -        - [ ] `io.flush()` -        - [ ] `io.input()` +        - [x] `io.flush()` +        - [ ] `io.input()`: partially implemented          - [ ] `io.lines()`          - [ ] `io.open()` -        - [ ] `io.output()` +        - [ ] `io.output()`: partially implemented          - [ ] `io.popen()`          - [ ] `io.read()`          - [ ] `io.tmpfile()` -        - [ ] `file:flush()`          - [ ] `file:lines()`          - [ ] `file:read()`          - [ ] `file:setvbuf()` diff --git a/src/liolib.js b/src/liolib.js index 575b3ec..51e18ee 100644 --- a/src/liolib.js +++ b/src/liolib.js @@ -78,6 +78,23 @@ const getiofile = function(L, findex) {      return p.f;  }; +const g_iofile = function(L, f, mode) { +    if (!lua.lua_isnoneornil(L, 1)) { +        lauxlib.luaL_error(L, lua.to_luastring("opening files not yet implemented")); +    } +    /* return current value */ +    lua.lua_getfield(L, lua.LUA_REGISTRYINDEX, f); +    return 1; +}; + +const io_input = function(L) { +  return g_iofile(L, IO_INPUT, "r"); +}; + +const io_output = function(L) { +  return g_iofile(L, IO_OUTPUT, "w"); +}; +  const g_write = function(L, f, arg) {      let nargs = lua.lua_gettop(L) - arg;      let status = true; @@ -105,14 +122,30 @@ const f_write = function(L) {      return g_write(L, f, 2);  }; +const io_flush = function (L) { +    /* stub, as node doesn't have synchronized buffered IO */ +    getiofile(L, IO_OUTPUT); +    return lauxlib.luaL_fileresult(L, true, null, null); +}; + +const f_flush = function (L) { +    /* stub, as node doesn't have synchronized buffered IO */ +    tofile(L); +    return lauxlib.luaL_fileresult(L, true, null, null); +}; +  const iolib = {      "close": io_close, +    "flush": io_flush, +    "input": io_input, +    "output": io_output,      "type": io_type,      "write": io_write  };  const flib = {      "close": io_close, +    "flush": f_flush,      "write": f_write,      "__tostring": f_tostring  }; diff --git a/src/loadlib.js b/src/loadlib.js index c43f498..4e5ee60 100644 --- a/src/loadlib.js +++ b/src/loadlib.js @@ -321,30 +321,40 @@ const searcher_preload = function(L) {      return 1;  }; -const findloader = function(L, name) { +const findloader = function(L, name, ctx, k) {      let msg = [];  /* to build error message */      /* push 'package.searchers' to index 3 in the stack */      if (lua.lua_getfield(L, lua.lua_upvalueindex(1), lua.to_luastring("searchers", true)) !== lua.LUA_TTABLE)          lauxlib.luaL_error(L, lua.to_luastring("'package.searchers' must be a table")); +    let ctx2 = {name: name, i: 1, msg: msg, ctx: ctx, k: k}; +    return findloader_cont(L, lua.LUA_OK, ctx2); +}; + +const findloader_cont = function(L, status, ctx) {      /*  iterate over available searchers to find a loader */ -    for (let i = 1; ; i++) { -        if (lua.lua_rawgeti(L, 3, i) === lua.LUA_TNIL) {  /* no more searchers? */ -            lua.lua_pop(L, 1);  /* remove nil */ -            lua.lua_pushstring(L, msg);  /* create error message */ -            lauxlib.luaL_error(L, lua.to_luastring("module '%s' not found:%s"), name, lua.lua_tostring(L, -1)); +    for (; ; ctx.i++) { +        if (status === lua.LUA_OK) { +            if (lua.lua_rawgeti(L, 3, ctx.i) === lua.LUA_TNIL) {  /* no more searchers? */ +                lua.lua_pop(L, 1);  /* remove nil */ +                lua.lua_pushstring(L, ctx.msg);  /* create error message */ +                lauxlib.luaL_error(L, lua.to_luastring("module '%s' not found:%s"), ctx.name, lua.lua_tostring(L, -1)); +            } +            lua.lua_pushstring(L, ctx.name); +            lua.lua_callk(L, 1, 2, ctx, findloader_cont);  /* call it */ +        } else { +            status = lua.LUA_OK;          } -        lua.lua_pushstring(L, name); -        lua.lua_call(L, 1, 2);  /* call it */          if (lua.lua_isfunction(L, -2))  /* did it find a loader? */ -            return;  /* module loader found */ +            break;  /* module loader found */          else if (lua.lua_isstring(L, -2)) {  /* searcher returned error message? */              lua.lua_pop(L, 1);  /* remove extra return */ -            msg.push(...lua.lua_tostring(L, -1)); +            ctx.msg.push(...lua.lua_tostring(L, -1));              lua.lua_remove(L, -1);  /* concatenate error message */          }          else              lua.lua_pop(L, 2);  /* remove both returns */      } +    return ctx.k(L, lua.LUA_OK, ctx.ctx);  };  const ll_require = function(L) { @@ -356,10 +366,20 @@ const ll_require = function(L) {        return 1;  /* package is already loaded */      /* else must load package */      lua.lua_pop(L, 1);  /* remove 'getfield' result */ -    findloader(L, name); +    let ctx = name; +    return findloader(L, name, ctx, ll_require_cont); +}; + +const ll_require_cont = function(L, status, ctx) { +    let name = ctx;      lua.lua_pushstring(L, name);  /* pass name as argument to module loader */      lua.lua_insert(L, -2);  /* name is 1st argument (before search data) */ -    lua.lua_call(L, 2, 1);  /* run loader to load module */ +    lua.lua_callk(L, 2, 1, ctx, ll_require_cont2) +    return ll_require_cont2(L, lua.LUA_OK, ctx);  /* run loader to load module */ +}; + +const ll_require_cont2 = function(L, status, ctx) { +    let name = ctx;      if (!lua.lua_isnil(L, -1))  /* non-nil return? */        lua.lua_setfield(L, 2, name);  /* LOADED[name] = returned value */      if (lua.lua_getfield(L, 2, name) == lua.LUA_TNIL) {   /* module set no value? */  | 
