From 0a006ad403733a85abe5be3f242c0264a4556afb Mon Sep 17 00:00:00 2001 From: Benoit Giannangeli Date: Fri, 24 Feb 2017 15:05:44 +0100 Subject: math.abs, math.sin, math.cos, math.tan, math.asin, math.acos, math.atan --- README.md | 34 +++++++++++++++++++++-- src/lapi.js | 10 +++++++ src/lauxlib.js | 10 ++++++- src/linit.js | 8 ++++-- src/lmathlib.js | 70 ++++++++++++++++++++++++++++++++++++++++++++++ src/lvm.js | 2 +- tests/lmathlib.js | 83 +++++++++++++++++++++++++++++++++++++++++++++++++++++++ 7 files changed, 209 insertions(+), 8 deletions(-) create mode 100644 src/lmathlib.js create mode 100644 tests/lmathlib.js diff --git a/README.md b/README.md index d0bbae9..ded30f7 100644 --- a/README.md +++ b/README.md @@ -37,7 +37,9 @@ - [x] lua_gettable - [x] lua_gettop - [x] lua_insert + - [x] lua_isinteger - [x] lua_isnoneornil + - [x] lua_isnumber - [x] lua_isstring - [x] lua_istable - [x] lua_isyieldable @@ -111,11 +113,9 @@ - [ ] lua_isboolean - [ ] lua_iscfunction - [ ] lua_isfunction - - [ ] lua_isinteger - [ ] lua_islightuserdata - [ ] lua_isnil - [ ] lua_isnone - - [ ] lua_isnumber - [ ] lua_isthread - [ ] lua_isuserdata - [ ] lua_newuserdata @@ -149,6 +149,7 @@ - [x] luaL_checkany - [x] luaL_checkinteger - [x] luaL_checklstring + - [x] luaL_checknumber - [x] luaL_checkstack - [x] luaL_checktype - [x] luaL_error @@ -170,7 +171,6 @@ - [ ] luaL_addchar - [ ] luaL_addsize - [ ] luaL_buffinitsize - - [ ] luaL_checknumber - [ ] luaL_checkoption - [ ] luaL_checkstring - [ ] luaL_checkudata @@ -206,6 +206,34 @@ - [ ] load - [x] Coroutine - [x] Table + - [ ] Math + - [x] math.abs + - [x] math.acos + - [x] math.asin + - [x] math.atan + - [x] math.cos + - [x] math.sin + - [x] math.tan + - [ ] math.ceil + - [ ] math.deg + - [ ] math.exp + - [ ] math.floor + - [ ] math.fmod + - [ ] math.huge + - [ ] math.log + - [ ] math.max + - [ ] math.maxinteger + - [ ] math.min + - [ ] math.mininteger + - [ ] math.modf + - [ ] math.pi + - [ ] math.rad + - [ ] math.random + - [ ] math.randomseed + - [ ] math.sqrt + - [ ] math.tointeger + - [ ] math.type + - [ ] math.ult - [ ] Run [Lua test suite](https://github.com/lua/tests) - [ ] DOM API binding - [ ] Parse Lua diff --git a/src/lapi.js b/src/lapi.js index b39046b..4eb55cd 100644 --- a/src/lapi.js +++ b/src/lapi.js @@ -603,6 +603,14 @@ const lua_istable = function(L, idx) { return index2addr(L, idx).ttistable(); }; +const lua_isinteger = function(L, idx) { + return index2addr(L, idx).ttisinteger(); +}; + +const lua_isnumber = function(L, idx) { + return lvm.tonumber(L, idx); +}; + const lua_isstring = function(L, idx) { let o = index2addr(L, idx); return o.ttisstring() || o.ttisnumber(); @@ -789,7 +797,9 @@ module.exports.lua_getmetatable = lua_getmetatable; module.exports.lua_gettable = lua_gettable; module.exports.lua_gettop = lua_gettop; module.exports.lua_insert = lua_insert; +module.exports.lua_isinteger = lua_isinteger; module.exports.lua_isnoneornil = lua_isnoneornil; +module.exports.lua_isnumber = lua_isnumber; module.exports.lua_isstring = lua_isstring; module.exports.lua_istable = lua_istable; module.exports.lua_len = lua_len; diff --git a/src/lauxlib.js b/src/lauxlib.js index 3774309..728469a 100644 --- a/src/lauxlib.js +++ b/src/lauxlib.js @@ -179,6 +179,13 @@ const interror = function(L, arg) { tag_error(L, arg, CT.LUA_TNUMBER); }; +const luaL_checknumber = function(L, arg) { + let d = lapi.lua_tonumber(L, arg); + if (d === false) + tag_error(L, arg, CT.LUA_TNUMBER); + return d; +}; + const luaL_checkinteger = function(L, arg) { let d = lapi.lua_tointeger(L, arg); if (d === false) @@ -356,17 +363,18 @@ const luaL_newlib = function(L, l) { }; module.exports.LUA_LOADED_TABLE = LUA_LOADED_TABLE; +module.exports.luaL_Buffer = luaL_Buffer; module.exports.luaL_addlstring = luaL_addlstring; module.exports.luaL_addstring = luaL_addstring; module.exports.luaL_addvalue = luaL_addvalue; module.exports.luaL_argcheck = luaL_argcheck; module.exports.luaL_argerror = luaL_argerror; -module.exports.luaL_Buffer = luaL_Buffer; module.exports.luaL_buffinit = luaL_buffinit; module.exports.luaL_callmeta = luaL_callmeta; module.exports.luaL_checkany = luaL_checkany; module.exports.luaL_checkinteger = luaL_checkinteger; module.exports.luaL_checklstring = luaL_checklstring; +module.exports.luaL_checknumber = luaL_checknumber; module.exports.luaL_checkstack = luaL_checkstack; module.exports.luaL_checktype = luaL_checktype; module.exports.luaL_error = luaL_error; diff --git a/src/linit.js b/src/linit.js index eb8caf2..36c0121 100644 --- a/src/linit.js +++ b/src/linit.js @@ -9,11 +9,13 @@ const lualib = require('./lualib.js'); const lbaselib = require('./lbaselib.js'); const lcorolib = require('./lcorolib.js'); const ltablib = require('./ltablib.js'); +const lmathlib = require('./lmathlib.js'); const loadedlibs = { - [lualib.LUA_TABLIBNAME]: ltablib.luaopen_table, - [lualib.LUA_COLIBNAME]: lcorolib.luaopen_coroutine, - "_G": lbaselib.luaopen_base + [lualib.LUA_MATHLIBNAME]: lmathlib.luaopen_math, + [lualib.LUA_TABLIBNAME]: ltablib.luaopen_table, + [lualib.LUA_COLIBNAME]: lcorolib.luaopen_coroutine, + "_G": lbaselib.luaopen_base }; const luaL_openlibs = function(L) { diff --git a/src/lmathlib.js b/src/lmathlib.js new file mode 100644 index 0000000..d1daca5 --- /dev/null +++ b/src/lmathlib.js @@ -0,0 +1,70 @@ +/* jshint esversion: 6 */ +"use strict"; + +const assert = require('assert'); + +const lua = require('./lua.js'); +const lapi = require('./lapi.js'); +const lauxlib = require('./lauxlib.js'); +const lstate = require('./lstate.js'); +const ldo = require('./ldo.js'); +const ldebug = require('./ldebug.js'); +const llimit = require('./llimit.js'); +const CT = lua.constant_types; +const TS = lua.thread_status; + + +const math_abs = function(L) { + if (lapi.lua_isinteger(L, 1)) + lapi.lua_pushinteger(L, Math.abs(lapi.lua_tointeger(L, 1))); + else + lapi.lua_pushnumber(L, Math.abs(lauxlib.luaL_checknumber(L, 1))); + return 1; +}; + +const math_sin = function(L) { + lapi.lua_pushnumber(L, Math.sin(lauxlib.luaL_checknumber(L, 1))); + return 1; +}; + +const math_cos = function(L) { + lapi.lua_pushnumber(L, Math.cos(lauxlib.luaL_checknumber(L, 1))); + return 1; +}; + +const math_tan = function(L) { + lapi.lua_pushnumber(L, Math.tan(lauxlib.luaL_checknumber(L, 1))); + return 1; +}; + +const math_asin = function(L) { + lapi.lua_pushnumber(L, Math.asin(lauxlib.luaL_checknumber(L, 1))); + return 1; +}; + +const math_acos = function(L) { + lapi.lua_pushnumber(L, Math.acos(lauxlib.luaL_checknumber(L, 1))); + return 1; +}; + +const math_atan = function(L) { + lapi.lua_pushnumber(L, Math.atan(lauxlib.luaL_checknumber(L, 1))); + return 1; +}; + +const mathlib = { + "abs": math_abs, + "sin": math_sin, + "cos": math_cos, + "tan": math_tan, + "asin": math_asin, + "acos": math_acos, + "atan": math_atan +}; + +const luaopen_math = function(L) { + lauxlib.luaL_newlib(L, mathlib); + return 1; +}; + +module.exports.luaopen_math = luaopen_math; \ No newline at end of file diff --git a/src/lvm.js b/src/lvm.js index a0822cc..d623a72 100644 --- a/src/lvm.js +++ b/src/lvm.js @@ -845,7 +845,7 @@ const luaV_tointeger = function(obj, mode) { }; const tointeger = function(o) { - return o.ttisinteger() ? o.value : luaV_tointeger(o, 0); + return o.ttisinteger() ? o.value|0 : luaV_tointeger(o, 0); }; const tonumber = function(v) { diff --git a/tests/lmathlib.js b/tests/lmathlib.js new file mode 100644 index 0000000..4c886f1 --- /dev/null +++ b/tests/lmathlib.js @@ -0,0 +1,83 @@ +/*jshint esversion: 6 */ +"use strict"; + +const test = require('tape'); +const beautify = require('js-beautify').js_beautify; + +const tests = require("./tests.js"); +const getState = tests.getState; +const toByteCode = tests.toByteCode; + +const VM = require("../src/lvm.js"); +const ldo = require("../src/ldo.js"); +const lapi = require("../src/lapi.js"); +const lauxlib = require("../src/lauxlib.js"); +const lua = require('../src/lua.js'); +const linit = require('../src/linit.js'); +const lstate = require('../src/lstate.js'); +const CT = lua.constant_types; + + +test('math.abs, math.sin, math.cos, math.tan, math.asin, math.acos, math.atan', function (t) { + let luaCode = ` + return math.abs(-10), math.abs(-10.5), math.cos(10), math.tan(10), math.asin(1), math.acos(0.5), math.atan(10) + `, L; + + t.plan(8); + + t.doesNotThrow(function () { + + let bc = toByteCode(luaCode).dataView; + + L = lauxlib.luaL_newstate(); + + linit.luaL_openlibs(L); + + lapi.lua_load(L, bc, "test-math.abs"); + + lapi.lua_call(L, 0, -1); + + }, "JS Lua program ran without error"); + + t.strictEqual( + lapi.lua_tointeger(L, -7), + 10, + "Correct element(s) on the stack" + ); + + t.strictEqual( + lapi.lua_tonumber(L, -6), + 10.5, + "Correct element(s) on the stack" + ); + + t.strictEqual( + lapi.lua_tonumber(L, -5), + -0.8390715290764524, + "Correct element(s) on the stack" + ); + + t.strictEqual( + lapi.lua_tonumber(L, -4), + 0.6483608274590866, + "Correct element(s) on the stack" + ); + + t.strictEqual( + lapi.lua_tonumber(L, -3), + 1.5707963267948966, + "Correct element(s) on the stack" + ); + + t.strictEqual( + lapi.lua_tonumber(L, -2), + 1.0471975511965979, + "Correct element(s) on the stack" + ); + + t.strictEqual( + lapi.lua_tonumber(L, -1), + 1.4711276743037347, + "Correct element(s) on the stack" + ); +}); \ No newline at end of file -- cgit v1.2.3-70-g09d2