From 5f6d2e34f69d14c57e7f2964aa951c8dab4efc99 Mon Sep 17 00:00:00 2001 From: Benoit Giannangeli Date: Tue, 18 Apr 2017 10:37:02 +0200 Subject: os.time --- src/linit.js | 4 ++- src/loslib.js | 78 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++ src/lualib.js | 2 +- tests/loslib.js | 38 ++++++++++++++++++++++++++++ tests/lua-tests | 2 +- 5 files changed, 121 insertions(+), 3 deletions(-) create mode 100644 src/loslib.js create mode 100644 tests/loslib.js diff --git a/src/linit.js b/src/linit.js index 9425ae7..fa827cb 100644 --- a/src/linit.js +++ b/src/linit.js @@ -12,15 +12,17 @@ const lstrlib = require('./lstrlib.js'); const ltablib = require('./ltablib.js'); const lutf8lib = require('./lutf8lib.js'); const ldblib = require('./ldblib.js'); +const loslib = require('./loslib.js'); const lualib = require('./lualib.js'); const loadedlibs = { [lualib.LUA_COLIBNAME]: lcorolib.luaopen_coroutine, + [lualib.LUA_DBLIBNAME]: ldblib.luaopen_debug, [lualib.LUA_MATHLIBNAME]: lmathlib.luaopen_math, + [lualib.LUA_OSLIBNAME]: loslib.luaopen_os, [lualib.LUA_STRLIBNAME]: lstrlib.luaopen_string, [lualib.LUA_TABLIBNAME]: ltablib.luaopen_table, [lualib.LUA_UTF8LIBNAME]: lutf8lib.luaopen_utf8, - [lualib.LUA_DBLIBNAME]: ldblib.luaopen_debug, "_G": lbaselib.luaopen_base }; diff --git a/src/loslib.js b/src/loslib.js new file mode 100644 index 0000000..20675a1 --- /dev/null +++ b/src/loslib.js @@ -0,0 +1,78 @@ +"use strict"; + +const assert = require('assert'); + +const lua = require('./lua.js'); +const char = lua.char; +const lapi = require('./lapi.js'); +const lauxlib = require('./lauxlib.js'); +const ldebug = require('./ldebug.js'); + +const setfield = function(L, key, value) { + lapi.lua_pushinteger(L, value); + lapi.lua_setfield(L, -2, key); +}; + +const setallfields = function(L, time) { + setfield(L, "sec", time.getSeconds()); + setfield(L, "min", time.getMinutes()); + setfield(L, "hour", time.getHours()); + setfield(L, "day", time.getDate()); + setfield(L, "month", time.getMonth()); + setfield(L, "year", time.getYear()); + setfield(L, "wday", time.getDay()); + let now = new Date(); + setfield(L, "yday", Math.floor((now - (new Date(now.getFullYear(), 0, 0))) / (1000 * 60 * 60 * 24))); + // setboolfield(L, "isdst", time.get); +}; + +const L_MAXDATEFIELD = (Number.MAX_SAFE_INTEGER / 2); + +const getfield = function(L, key, d, delta) { + let t = lapi.lua_getfield(L, -1, lua.to_luastring(key)); /* get field and its type */ + let res = lapi.lua_tointegerx(L, -1); + if (res !== false) { /* field is not an integer? */ + if (t != lua.CT.LUA_TNIL) /* some other value? */ + return lauxlib.luaL_error(L, `field '${key}' is not an integer`); + else if (d < 0) /* absent field; no default? */ + return lauxlib.luaL_error(L, `field '${key}' missing in date table`); + res = d; + } + else { + if (!(-L_MAXDATEFIELD <= res && res <= L_MAXDATEFIELD)) + return lauxlib.luaL_error(L, `field '${key}' is out-of-bound`); + res -= delta; + } + lapi.lua_pop(L, 1); + return res; +}; + +const os_time = function(L) { + let t = new Date(); + if (!lapi.lua_isnoneornil(L, 1)) /* called with arg */{ + lauxlib.luaL_checktype(L, 1, lua.CT.LUA_TTABLE); /* make sure table is at the top */ + lapi.lua_settop(L, 1); + t.setSeconds(getfield(L, "sec", 0, 0)); + t.setSeconds(getfield(L, "min", 0, 0)); + t.setSeconds(getfield(L, "hour", 12, 0)); + t.setSeconds(getfield(L, "day", -1, 0)); + t.setSeconds(getfield(L, "month", -1, 1)); + t.setSeconds(getfield(L, "year", -1, 1900)); + setallfields(L, t); + } + + lapi.lua_pushinteger(L, Math.floor(t / 1000)); + return 1; +}; + + +const syslib = { + "time": os_time +}; + +const luaopen_os = function(L) { + lauxlib.luaL_newlib(L, syslib); + return 1; +}; + +module.exports.luaopen_os = luaopen_os; diff --git a/src/lualib.js b/src/lualib.js index 9751302..327673e 100644 --- a/src/lualib.js +++ b/src/lualib.js @@ -20,7 +20,7 @@ module.exports.LUA_IOLIBNAME = LUA_IOLIBNAME; const LUA_OSLIBNAME = "os"; module.exports.LUA_OSLIBNAME = LUA_OSLIBNAME; -// module.exports[LUA_OSLIBNAME] = require("./loslib.js").luaopen_os; +module.exports[LUA_OSLIBNAME] = require("./loslib.js").luaopen_os; const LUA_STRLIBNAME = "string"; module.exports.LUA_STRLIBNAME = LUA_STRLIBNAME; diff --git a/tests/loslib.js b/tests/loslib.js new file mode 100644 index 0000000..1bb217f --- /dev/null +++ b/tests/loslib.js @@ -0,0 +1,38 @@ +"use strict"; + +const test = require('tape'); + +const lapi = require("../src/lapi.js"); +const lauxlib = require("../src/lauxlib.js"); +const lua = require('../src/lua.js'); +const linit = require('../src/linit.js'); + +test('os.time', function (t) { + let luaCode = ` + return os.time() + `, L; + + t.plan(3); + + t.doesNotThrow(function () { + + L = lauxlib.luaL_newstate(); + + linit.luaL_openlibs(L); + + lauxlib.luaL_loadstring(L, lua.to_luastring(luaCode)); + + }, "Lua program loaded without error"); + + t.doesNotThrow(function () { + + lapi.lua_call(L, 0, -1); + + }, "Lua program ran without error"); + + t.ok( + lapi.lua_isinteger(L, -1), + "Correct element(s) on the stack" + ); + +}); diff --git a/tests/lua-tests b/tests/lua-tests index 01eded4..21fb72d 160000 --- a/tests/lua-tests +++ b/tests/lua-tests @@ -1 +1 @@ -Subproject commit 01eded4b34159a77f61b56c5567c74f169d3b1ea +Subproject commit 21fb72de668a3307958d6a6d71770ae2118ba1d3 -- cgit v1.2.3-70-g09d2