diff options
author | Benoit Giannangeli <giann008@gmail.com> | 2017-02-26 15:13:22 +0100 |
---|---|---|
committer | Benoit Giannangeli <giann008@gmail.com> | 2017-02-26 22:54:27 +0100 |
commit | 94a301a27a8a75c4684790a99a898262b8354f68 (patch) | |
tree | b8bc9c755cdd79f1027aef877a400de1356683c9 /src/lmathlib.js | |
parent | 616d80301734074e55cedec8ba187b5cab89ea95 (diff) | |
download | fengari-94a301a27a8a75c4684790a99a898262b8354f68.tar.gz fengari-94a301a27a8a75c4684790a99a898262b8354f68.tar.bz2 fengari-94a301a27a8a75c4684790a99a898262b8354f68.zip |
math.random/randomseed
Diffstat (limited to 'src/lmathlib.js')
-rw-r--r-- | src/lmathlib.js | 134 |
1 files changed, 103 insertions, 31 deletions
diff --git a/src/lmathlib.js b/src/lmathlib.js index f4cc978..54bdc46 100644 --- a/src/lmathlib.js +++ b/src/lmathlib.js @@ -1,18 +1,55 @@ /* jshint esversion: 6 */ "use strict"; -const assert = require('assert'); +const assert = require('assert'); +const seedrandom = require('seedrandom'); -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 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 luaconf = require('./luaconf.js'); +const CT = lua.constant_types; +const TS = lua.thread_status; +var RNG = seedrandom(); + +const math_randomseed = function(L) { + RNG = seedrandom(Math.abs(lauxlib.luaL_checknumber(L, 1))); +}; + +const math_random = function(L) { + let low, up; + let r = RNG(); + switch (lapi.lua_gettop(L)) { /* check number of arguments */ + case 0: + lapi.lua_pushnumber(L, r); /* Number between 0 and 1 */ + return 1; + case 1: { + low = 1; + up = lauxlib.luaL_checkinteger(L, 1); + break; + } + case 2: { + low = lauxlib.luaL_checkinteger(L, 1); + up = lauxlib.luaL_checkinteger(L, 2); + break; + } + default: return lauxlib.luaL_error(L, "wrong number of arguments"); + } + + /* random integer in the interval [low, up] */ + lauxlib.luaL_argcheck(L, low <= up, 1, "interval is empty"); + lauxlib.luaL_argcheck(L, low >= 0 || up <= Number.MAX_SAFE_INTEGER + low, 1, + "interval too large"); + + r *= (up - low) + 1; + lapi.lua_pushinteger(L, r + low); + return 1; +}; const math_abs = function(L) { if (lapi.lua_isinteger(L, 1)) @@ -53,7 +90,7 @@ const math_atan = function(L) { }; const math_toint = function(L) { - let n = lapi.lua_tointegerx(L, 1) + let n = lapi.lua_tointegerx(L, 1); if (n !== false) lapi.lua_pushinteger(L, n); else { @@ -91,6 +128,7 @@ const math_ceil = function(L) { const math_sqrt = function(L) { lapi.lua_pushnumber(L, Math.sqrt(lauxlib.luaL_checknumber(L, 1))); + return 1; }; const math_ult = function(L) { @@ -102,6 +140,7 @@ const math_ult = function(L) { const math_log = function(L) { let x = lauxlib.luaL_checknumber(L, 1); + let res; if (lapi.lua_isnoneornil(L, 2)) res = Math.log(x); else { @@ -129,6 +168,7 @@ const math_deg = function(L) { const math_rad = function(L) { lapi.lua_pushnumber(L, lauxlib.luaL_checknumber(L, 1) * (Math.PI / 180)); + return 1; }; const math_min = function(L) { @@ -168,27 +208,59 @@ const math_type = function(L) { return 1; }; +const math_fmod = function(L) { + if (lapi.lua_isinteger(L, 1) && lapi.lua_isinteger(L, 2)) { + let d = lapi.lua_tointeger(L, 2); + if (Math.abs(d) + 1 <= 1) { + lauxlib.luaL_argcheck(L, d !== 0, 2, "zero"); + lapi.lua_pushinteger(L, 0); + } else + lapi.lua_pushinteger(L, lapi.lua_tointeger(L, 1) % d); + } else { + let a = lauxlib.luaL_checknumber(L, 1); + let b = lauxlib.luaL_checknumber(L, 2); + lapi.lua_pushnumber(L, Number((a - (Math.floor(a / b) * b)).toPrecision(8))); + } + return 1; +}; + +const math_modf = function(L) { + if (lapi.lua_isinteger(L, 1)) { + lapi.lua_settop(L, 1); /* number is its own integer part */ + lapi.lua_pushnumber(L, 0); /* no fractional part */ + } else { + let n = lauxlib.luaL_checknumber(L, 1); + let ip = n < 0 ? Math.ceil(n) : Math.floor(n); + pushnumint(L, ip); + lapi.lua_pushnumber(L, n === ip ? 0 : n - ip); + } + return 2; +}; + const mathlib = { - "abs": math_abs, - "acos": math_acos, - "asin": math_asin, - "atan": math_atan, - "ceil": math_ceil, - "cos": math_cos, - "deg": math_deg, - "exp": math_exp, - "floor": math_floor, - "log": math_log, - "max": math_max, - "min": math_min, - "rad": math_rad, - "sin": math_sin, - "sqrt": math_sqrt, - "sqrt": math_sqrt, - "tan": math_tan, - "tointeger": math_toint, - "type": math_type, - "ult": math_ult + "abs": math_abs, + "acos": math_acos, + "asin": math_asin, + "atan": math_atan, + "ceil": math_ceil, + "cos": math_cos, + "deg": math_deg, + "exp": math_exp, + "floor": math_floor, + "fmod": math_fmod, + "log": math_log, + "max": math_max, + "min": math_min, + "modf": math_modf, + "rad": math_rad, + "random": math_random, + "randomseed": math_randomseed, + "sin": math_sin, + "sqrt": math_sqrt, + "tan": math_tan, + "tointeger": math_toint, + "type": math_type, + "ult": math_ult }; const luaopen_math = function(L) { |