aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/lapi.js2
-rw-r--r--src/lmathlib.js134
-rw-r--r--src/luaconf.js5
-rw-r--r--src/lvm.js2
4 files changed, 108 insertions, 35 deletions
diff --git a/src/lapi.js b/src/lapi.js
index 4eb55cd..d0c099f 100644
--- a/src/lapi.js
+++ b/src/lapi.js
@@ -545,7 +545,7 @@ const lua_topointer = function(L, idx) {
const lua_compare = function(L, index1, index2, op) {
let o1 = index2addr(L, index1);
- let o2 = index2addr(L, index1);
+ let o2 = index2addr(L, index2);
return lua_compare_(L, o1, o2, op);
};
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) {
diff --git a/src/luaconf.js b/src/luaconf.js
index 7297b28..f0066de 100644
--- a/src/luaconf.js
+++ b/src/luaconf.js
@@ -20,5 +20,6 @@ const lua_numbertointeger = function(n) {
return n|0;
};
-module.exports.LUAI_MAXSTACK = LUAI_MAXSTACK;
-module.exports.LUA_IDSIZE = LUA_IDSIZE; \ No newline at end of file
+module.exports.LUAI_MAXSTACK = LUAI_MAXSTACK;
+module.exports.LUA_IDSIZE = LUA_IDSIZE;
+module.exports.lua_numbertointeger = lua_numbertointeger; \ No newline at end of file
diff --git a/src/lvm.js b/src/lvm.js
index d623a72..d987cc1 100644
--- a/src/lvm.js
+++ b/src/lvm.js
@@ -838,7 +838,7 @@ const luaV_tointeger = function(obj, mode) {
} else if (obj.ttisinteger()) {
return obj.value|0;
} else if (obj.ttisstring()) {
- return luaV_tointeger(parseFloat(obj.value), mode); // TODO: luaO_str2num
+ return luaV_tointeger(new TValue(CT.LUA_TNUMFLT, parseFloat(obj.value)), mode); // TODO: luaO_str2num
}
return false;