UNPKG

tcl-js

Version:

tcl-js is a tcl intepreter written completely in Typescript. It is meant to replicate the tcl-sh interpreter as closely as possible.

278 lines (228 loc) 5.43 kB
import contains from './contains'; export function add(a, b) { return Number(a) + Number(b); } export function sub(a, b) { return a - b; } export function mul(a, b) { return a * b; } export function div(a, b) { return a / b; } export function mod(a, b) { return a % b; } export function concat(a, b) { return '' + a + b; } export function equal(a, b) { return a === b; } export function notEqual(a, b) { return a !== b; } export function greaterThan(a, b) { return a > b; } export function lessThan(a, b) { return a < b; } export function greaterThanEqual(a, b) { return a >= b; } export function lessThanEqual(a, b) { return a <= b; } export function andOperator(a, b) { return Boolean(a && b); } export function orOperator(a, b) { return Boolean(a || b); } export function inOperator(a, b) { return contains(b, a); } export function sinh(a) { return (Math.exp(a) - Math.exp(-a)) / 2; } export function cosh(a) { return (Math.exp(a) + Math.exp(-a)) / 2; } export function tanh(a) { if (a === Infinity) return 1; if (a === -Infinity) return -1; return (Math.exp(a) - Math.exp(-a)) / (Math.exp(a) + Math.exp(-a)); } export function asinh(a) { if (a === -Infinity) return a; return Math.log(a + Math.sqrt(a * a + 1)); } export function acosh(a) { return Math.log(a + Math.sqrt(a * a - 1)); } export function atanh(a) { return Math.log((1 + a) / (1 - a)) / 2; } export function log10(a) { return Math.log(a) * Math.LOG10E; } export function neg(a) { return -a; } export function not(a) { return !a; } export function trunc(a) { return a < 0 ? Math.ceil(a) : Math.floor(a); } export function random(a) { return Math.random() * (a || 1); } export function factorial(a) { // a! return gamma(a + 1); } export function bool(a) { if (a === 'yes' || a === 'true' || a === 'on') return true; if (a === 'no' || a === 'false' || a === 'off') return false; if (!a) return false; if (!isNaN(a) && parseInt(a, 10) > 0) return true; } export function fmod (a, b) { return a % b; }; export function max (...args) { args = args.sort(); return args[args.length -1]; }; export function min (...args) { args = args.sort(); return args[0]; }; function isInteger(value) { return isFinite(value) && value === Math.round(value); } var GAMMA_G = 4.7421875; var GAMMA_P = [ 0.99999999999999709182, 57.156235665862923517, -59.597960355475491248, 14.136097974741747174, -0.49191381609762019978, 0.33994649984811888699e-4, 0.46523628927048575665e-4, -0.98374475304879564677e-4, 0.15808870322491248884e-3, -0.21026444172410488319e-3, 0.2174396181152126432e-3, -0.16431810653676389022e-3, 0.84418223983852743293e-4, -0.2619083840158140867e-4, 0.36899182659531622704e-5, ]; // Gamma function from math.js export function gamma(n) { var t, x; if (isInteger(n)) { if (n <= 0) { return isFinite(n) ? Infinity : NaN; } if (n > 171) { return Infinity; // Will overflow } var value = n - 2; var res = n - 1; while (value > 1) { res *= value; value--; } if (res === 0) { res = 1; // 0! is per definition 1 } return res; } if (n < 0.5) { return Math.PI / (Math.sin(Math.PI * n) * gamma(1 - n)); } if (n >= 171.35) { return Infinity; // will overflow } if (n > 85.0) { // Extended Stirling Approx var twoN = n * n; var threeN = twoN * n; var fourN = threeN * n; var fiveN = fourN * n; return ( Math.sqrt((2 * Math.PI) / n) * Math.pow(n / Math.E, n) * (1 + 1 / (12 * n) + 1 / (288 * twoN) - 139 / (51840 * threeN) - 571 / (2488320 * fourN) + 163879 / (209018880 * fiveN) + 5246819 / (75246796800 * fiveN * n)) ); } --n; x = GAMMA_P[0]; for (var i = 1; i < GAMMA_P.length; ++i) { x += GAMMA_P[i] / (n + i); } t = n + GAMMA_G + 0.5; return Math.sqrt(2 * Math.PI) * Math.pow(t, n + 0.5) * Math.exp(-t) * x; } export function stringLength(s) { return String(s).length; } export function hypot() { var sum = 0; var larg = 0; for (var i = 0; i < arguments.length; i++) { var arg = Math.abs(arguments[i]); var div; if (larg < arg) { div = larg / arg; sum = sum * div * div + 1; larg = arg; } else if (arg > 0) { div = arg / larg; sum += div * div; } else { sum += arg; } } return larg === Infinity ? Infinity : larg * Math.sqrt(sum); } export function condition(cond, yep, nope) { return cond ? yep : nope; } /** * Decimal adjustment of a number. * From @escopecz. * * @param {Number} value The number. * @param {Integer} exp The exponent (the 10 logarithm of the adjustment base). * @return {Number} The adjusted value. */ export function roundTo(value, exp) { // If the exp is undefined or zero... if (typeof exp === 'undefined' || +exp === 0) { return Math.round(value); } value = +value; exp = -+exp; // If the value is not a number or the exp is not an integer... if (isNaN(value) || !(typeof exp === 'number' && exp % 1 === 0)) { return NaN; } // Shift value = value.toString().split('e'); value = Math.round(+(value[0] + 'e' + (value[1] ? +value[1] - exp : -exp))); // Shift back value = value.toString().split('e'); return +(value[0] + 'e' + (value[1] ? +value[1] + exp : exp)); }