summaryrefslogtreecommitdiff
path: root/src/lmathlib.js
diff options
context:
space:
mode:
authorBenoit Giannangeli <giann008@gmail.com>2017-02-26 15:13:22 +0100
committerBenoit Giannangeli <giann008@gmail.com>2017-02-26 22:54:27 +0100
commit94a301a27a8a75c4684790a99a898262b8354f68 (patch)
treeb8bc9c755cdd79f1027aef877a400de1356683c9 /src/lmathlib.js
parent616d80301734074e55cedec8ba187b5cab89ea95 (diff)
downloadfengari-94a301a27a8a75c4684790a99a898262b8354f68.tar.gz
fengari-94a301a27a8a75c4684790a99a898262b8354f68.tar.bz2
fengari-94a301a27a8a75c4684790a99a898262b8354f68.zip
math.random/randomseed
Diffstat (limited to 'src/lmathlib.js')
-rw-r--r--src/lmathlib.js134
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) {