From d360065e1b9797c572c175c9bb35b0b6c68b3649 Mon Sep 17 00:00:00 2001 From: Mahdi Dibaiee Date: Thu, 18 Jun 2015 17:32:28 +0430 Subject: [PATCH] rebuild --- equation.js | 103 +++++++++++++++++++++++++++++++++++++++++------- equation.min.js | 2 +- 2 files changed, 89 insertions(+), 16 deletions(-) diff --git a/equation.js b/equation.js index ceab195..8285bcc 100644 --- a/equation.js +++ b/equation.js @@ -247,10 +247,14 @@ var Equation = { */ equation: function equation(expression) { var stack = parseExpression(expression); + console.log(stack); var variables = []; - stack.forEach(function (a) { - if (typeof a === 'string' && !_.isNumber(a) && !_operators2['default'][a] && a === a.toLowerCase()) { + stack.forEach(function varCheck(a) { + if (Array.isArray(a)) { + return a.forEach(varCheck); + } + if (isVariable(a)) { // grouped variables like (y) need to have their parantheses removed variables.push(_.removeSymbols(a)); } @@ -261,15 +265,30 @@ var Equation = { args[_key] = arguments[_key]; } - expression = expression.replace(/[a-z]*/g, function (a) { + stack.forEach(function varCheck(a, i, arr) { + if (Array.isArray(a)) { + return a.forEach(varCheck); + } + var index = variables.indexOf(a); if (index > -1) { - return args[index] || 0; + // grouped variables like (y) need to have their parantheses removed + arr[i] = args[index]; } - return a; }); - return Equation.solve(expression); + stack = sortStack(stack); + stack = _.parseNumbers(stack); + stack = solveStack(stack); + // expression = expression.replace(/[a-z]*/g, a => { + // let index = variables.indexOf(a); + // if (index > -1) { + // return args[index] || 0; + // } + // return a; + // }); + + return stack; }; }, @@ -327,33 +346,50 @@ var MIN_PRECEDENCE = Math.min.apply(Math, _toConsumableArray(PRECEDENCES)); var parseExpression = function parseExpression(expression) { var stream = new _ReadStream2['default'](expression), stack = [], - record = ''; + record = '', + cur = undefined, + past = undefined; // Create an array of separated numbers & operators while (stream.next()) { - var cur = stream.current(), - past = stack.length - 1; + cur = stream.current(); + past = stack.length - 1; + if (cur === ' ') { continue; } // it's probably a function with a length more than one - if (!_.isNumber(cur) && !_operators2['default'][cur] && cur !== '.') { + if (!_.isNumber(cur) && !_operators2['default'][cur] && cur !== '.' && cur !== '(' && cur !== ')') { + record += cur; } else if (record.length) { + var beforeRecord = past - (record.length - 1); + if (isVariable(record) && _.isNumber(stack[beforeRecord])) { + stack.push('*'); + } stack.push(record, cur); record = ''; - } else if (_.isNumber(stack[stack.length - 1]) && (_.isNumber(cur) || cur === '.')) { - stack[stack.length - 1] += cur; + // numbers and decimals + } else if (_.isNumber(stack[past]) && (_.isNumber(cur) || cur === '.')) { + + stack[past] += cur; + + // negation sign } else if (stack[past] === '-') { - var beforeSign = stack[stack.length - 2]; + var beforeSign = stack[past - 1]; + // 2 / -5 is OK, pass if (_operators2['default'][beforeSign]) { stack[past] += cur; + + // (2+1) - 5 becomes (2+1) + -5 } else if (beforeSign === ')') { stack[past] = '+'; stack.push('-' + cur); + + // 2 - 5 is also OK, pass } else if (_.isNumber(beforeSign)) { stack.push(cur); } else { @@ -364,6 +400,10 @@ var parseExpression = function parseExpression(expression) { } } if (record.length) { + var beforeRecord = past - (record.length - 1); + if (isVariable(record) && _.isNumber(stack[beforeRecord])) { + stack.push('*'); + } stack.push(record); } @@ -530,7 +570,7 @@ var evaluate = function evaluate(stack) { var leftArguments = stack.slice(0, left), rightArguments = stack.slice(left + 1); - return (_operators$op = _operators2['default'][op]).fn.apply(_operators$op, _toConsumableArray(leftArguments).concat(_toConsumableArray(rightArguments))); + return fixFloat((_operators$op = _operators2['default'][op]).fn.apply(_operators$op, _toConsumableArray(leftArguments).concat(_toConsumableArray(rightArguments)))); }; /** @@ -590,8 +630,31 @@ var replaceConstants = function replaceConstants(expression) { }); }; +/** + * Fixes JavaScript's floating point precisions - Issue #5 + * + * @param {Number} number + * The number to fix + * @return {Number} + * Fixed number + */ +var fixFloat = function fixFloat(number) { + return +number.toFixed(15); +}; + +/** + * Recognizes variables such as x, y, z + * @param {String} a + * The string to check for + * @return {Boolean} + * true if variable, else false + */ +var isVariable = function isVariable(a) { + return typeof a === 'string' && !_.isNumber(a) && !_operators2['default'][a] && a === a.toLowerCase(); +}; + +exports.isVariable = isVariable; exports['default'] = Equation; -module.exports = exports['default']; },{"./constants":1,"./helpers":2,"./operators":4,"./readstream":5}],4:[function(require,module,exports){ 'use strict'; @@ -704,6 +767,16 @@ exports['default'] = { fn: Math.cot, format: '10', precedence: -1 + }, + round: { + fn: Math.round, + format: '10', + precedence: -1 + }, + floor: { + fn: Math.floor, + format: '10', + precedence: -1 } }; module.exports = exports['default']; diff --git a/equation.min.js b/equation.min.js index 5a02af2..920304a 100644 --- a/equation.min.js +++ b/equation.min.js @@ -1 +1 @@ -!function(a){if("object"==typeof exports&&"undefined"!=typeof module)module.exports=a();else if("function"==typeof define&&define.amd)define([],a);else{var b;b="undefined"!=typeof window?window:"undefined"!=typeof global?global:"undefined"!=typeof self?self:this,b.Equation=a()}}(function(){return function a(b,c,d){function e(g,h){if(!c[g]){if(!b[g]){var i="function"==typeof require&&require;if(!h&&i)return i(g,!0);if(f)return f(g,!0);var j=new Error("Cannot find module '"+g+"'");throw j.code="MODULE_NOT_FOUND",j}var k=c[g]={exports:{}};b[g][0].call(k.exports,function(a){var c=b[g][1][a];return e(c?c:a)},k,k.exports,a,b,c,d)}return c[g].exports}for(var f="function"==typeof require&&require,g=0;gd;++d)c=c[c.length-1];return c};c.dive=g;var h=function(a){function b(b,c){return a.apply(this,arguments)}return b.toString=function(){return a.toString()},b}(function(a,b){var c=void 0===arguments[2]?0:arguments[2];if(2>b)return{arr:a,index:c};var d=a.reduce(function(a,d,e){if(Array.isArray(d)){var f=h(d,b-1,e),g=f.arr,i=f.index,j=a.concat(g);return c=i,j}return a},[]);return{arr:d,index:c}});c.deep=h;var i=function(a){function b(b,c,d){return a.apply(this,arguments)}return b.toString=function(){return a.toString()},b}(function(a,b,c){var d=[];if(!b.some(Array.isArray))return a[b[0]]=c,c;var e=!0,f=!1,g=void 0;try{for(var h,j=b[Symbol.iterator]();!(e=(h=j.next()).done);e=!0){var k=h.value;d.push(i(a,k,c))}}catch(l){f=!0,g=l}finally{try{!e&&j["return"]&&j["return"]()}finally{if(f)throw g}}return d});c.diveTo=i;var j=function(a){function b(b){return a.apply(this,arguments)}return b.toString=function(){return a.toString()},b}(function(a){return Array.isArray(a)&&a.some(Array.isArray)?a.reduce(function(a,b){return a.concat(j(b))},[]):a});c.flatten=j;var k=function(a){return a.toString().replace(/\W/g,"")};c.removeSymbols=k},{}],3:[function(a,b,c){"use strict";var d=function(a){return a&&a.__esModule?a:{"default":a}},e=function(a,b){if(Array.isArray(a))return a;if(Symbol.iterator in Object(a)){var c=[],d=!0,e=!1,f=void 0;try{for(var g,h=a[Symbol.iterator]();!(d=(g=h.next()).done)&&(c.push(g.value),!b||c.length!==b);d=!0);}catch(i){e=!0,f=i}finally{try{!d&&h["return"]&&h["return"]()}finally{if(e)throw f}}return c}throw new TypeError("Invalid attempt to destructure non-iterable instance")},f=function(a){if(Array.isArray(a)){for(var b=0,c=Array(a.length);be;e++)d[e]=arguments[e];return a=a.replace(/[a-z]*/g,function(a){var b=c.indexOf(a);return b>-1?d[b]||0:a}),o.solve(a)}},registerOperator:function(a,b){j["default"][a]=b},registerConstant:function(a,b){l["default"][a]=b}},p=function(a){function b(b){return a.apply(this,arguments)}return b.toString=function(){return a.toString()},b}(function(a){return a.some(Array.isArray)?(a=a.map(function(a){return Array.isArray(a)?p(a):a}),p(a)):x(a)}),q=Object.keys(j["default"]).map(function(a){return j["default"][a].precedence}),r=Math.max.apply(Math,f(q)),s=Math.min.apply(Math,f(q)),t=function(a){for(var b=new h["default"](a),c=[],d="";b.next();){var e=b.current(),f=c.length-1;if(" "!==e)if(n.isNumber(e)||j["default"][e]||"."===e)if(d.length)c.push(d,e),d="";else if(n.isNumber(c[c.length-1])&&(n.isNumber(e)||"."===e))c[c.length-1]+=e;else if("-"===c[f]){var g=c[c.length-2];j["default"][g]?c[f]+=e:")"===g?(c[f]="+",c.push("-"+e)):n.isNumber(g)?c.push(e):c[f]+=e}else c.push(e);else d+=e}return d.length&&c.push(d),u(c)},u=function(a){var b=0;return a.reduce(function(a,c){return c.indexOf("(")>-1?(c.length>1?n.dive(a,b).push(c.replace("(",""),[]):n.dive(a,b).push([]),b++):")"===c?b--:n.dive(a,b).push(c),a},[])},v=function(a){var b="string"==typeof a?j["default"][a]:a;if(!b)return null;var c=b.format.split("1"),d=c[0].length,e=c[1].length;return{left:d,right:e}},w=function(a){function b(b){return a.apply(this,arguments)}return b.toString=function(){return a.toString()},b}(function(a){var b=!0,c=!1,d=void 0;try{for(var f,g=a.entries()[Symbol.iterator]();!(b=(f=g.next()).done);b=!0){var h=e(f.value,2),i=h[0],k=h[1];Array.isArray(k)&&a.splice(i,1,w(k))}}catch(l){c=!0,d=l}finally{try{!b&&g["return"]&&g["return"]()}finally{if(c)throw d}}for(var m=s;r>=m;m++)for(var i=0;iu;u++)t=[t];i-=q}}return a}),x=function(a){var b,c=y(a);if(!c)return a[0];var d=v(c),e=d.left,g=a.slice(0,e),h=a.slice(e+1);return(b=j["default"][c]).fn.apply(b,f(g).concat(f(h)))},y=function(a){var b=!0,c=!1,d=void 0;try{for(var e,f=a[Symbol.iterator]();!(b=(e=f.next()).done);b=!0){var g=e.value;if("string"==typeof g)return g}}catch(h){c=!0,d=h}finally{try{!b&&f["return"]&&f["return"]()}finally{if(c)throw d}}return null},z=function(a){return a.replace(/[A-Z]*/g,function(a){var b=l["default"][a];return b?"function"==typeof b?b():b:a})};c["default"]=o,b.exports=c["default"]},{"./constants":1,"./helpers":2,"./operators":4,"./readstream":5}],4:[function(a,b,c){"use strict";Object.defineProperty(c,"__esModule",{value:!0}),c["default"]={"^":{fn:function(a,b){return Math.pow(a,b)},format:"010",precedence:0},"*":{fn:function(a,b){return a*b},format:"010",precedence:1},"/":{fn:function(a,b){return a/b},format:"010",precedence:1},"%":{fn:function(a,b){return a%b},format:"010",precedence:1},"\\":{fn:function(a,b){return Math.floor(a/b)},format:"010",precedence:1},"+":{fn:function(a,b){return a+b},format:"010",precedence:2},"-":{fn:function(a,b){return a-b},format:"010",precedence:2},"!":{fn:function(a){for(var b=1,c=0;a>c;++c)b*=c;return b},format:"01",precedence:2},log:{fn:Math.log,format:"10",precedence:-1},ln:{fn:Math.log,format:"10",precedence:-1},lg:{fn:function(a){return Math.log(a)/Math.log(2)},format:"10",precedence:-1},sin:{fn:Math.sin,format:"10",precedence:-1},cos:{fn:Math.cos,format:"10",precedence:-1},tan:{fn:Math.tan,format:"10",precedence:-1},cot:{fn:Math.cot,format:"10",precedence:-1}},b.exports=c["default"]},{}],5:[function(a,b,c){"use strict";Object.defineProperty(c,"__esModule",{value:!0}),c["default"]=function(a){var b=0,c=[];return{next:function(){return c.push(a[b]),b>=a.length?null:a[b++]},current:function(){return a[b-1]},index:function(){return b-1},to:function(c){var d="",e=b+c;for(b=b;e>b;++b)d+=[a[b]];return d},drain:function(){return c.splice(0,c.length)},replace:function(a){function b(b,c,d){return a.apply(this,arguments)}return b.toString=function(){return a.toString()},b}(function(c,d,e){var f=a.split("");f.splice(c,d,e),a=f.join(""),b-=d-c}),go:function(a){b+=a},all:function(){return a}}},b.exports=c["default"]},{}]},{},[3])(3)}); \ No newline at end of file +!function(a){if("object"==typeof exports&&"undefined"!=typeof module)module.exports=a();else if("function"==typeof define&&define.amd)define([],a);else{var b;b="undefined"!=typeof window?window:"undefined"!=typeof global?global:"undefined"!=typeof self?self:this,b.Equation=a()}}(function(){return function a(b,c,d){function e(g,h){if(!c[g]){if(!b[g]){var i="function"==typeof require&&require;if(!h&&i)return i(g,!0);if(f)return f(g,!0);var j=new Error("Cannot find module '"+g+"'");throw j.code="MODULE_NOT_FOUND",j}var k=c[g]={exports:{}};b[g][0].call(k.exports,function(a){var c=b[g][1][a];return e(c?c:a)},k,k.exports,a,b,c,d)}return c[g].exports}for(var f="function"==typeof require&&require,g=0;gd;++d)c=c[c.length-1];return c};c.dive=g;var h=function(a){function b(b,c){return a.apply(this,arguments)}return b.toString=function(){return a.toString()},b}(function(a,b){var c=void 0===arguments[2]?0:arguments[2];if(2>b)return{arr:a,index:c};var d=a.reduce(function(a,d,e){if(Array.isArray(d)){var f=h(d,b-1,e),g=f.arr,i=f.index,j=a.concat(g);return c=i,j}return a},[]);return{arr:d,index:c}});c.deep=h;var i=function(a){function b(b,c,d){return a.apply(this,arguments)}return b.toString=function(){return a.toString()},b}(function(a,b,c){var d=[];if(!b.some(Array.isArray))return a[b[0]]=c,c;var e=!0,f=!1,g=void 0;try{for(var h,j=b[Symbol.iterator]();!(e=(h=j.next()).done);e=!0){var k=h.value;d.push(i(a,k,c))}}catch(l){f=!0,g=l}finally{try{!e&&j["return"]&&j["return"]()}finally{if(f)throw g}}return d});c.diveTo=i;var j=function(a){function b(b){return a.apply(this,arguments)}return b.toString=function(){return a.toString()},b}(function(a){return Array.isArray(a)&&a.some(Array.isArray)?a.reduce(function(a,b){return a.concat(j(b))},[]):a});c.flatten=j;var k=function(a){return a.toString().replace(/\W/g,"")};c.removeSymbols=k},{}],3:[function(a,b,c){"use strict";var d=function(a){return a&&a.__esModule?a:{"default":a}},e=function(a,b){if(Array.isArray(a))return a;if(Symbol.iterator in Object(a)){var c=[],d=!0,e=!1,f=void 0;try{for(var g,h=a[Symbol.iterator]();!(d=(g=h.next()).done)&&(c.push(g.value),!b||c.length!==b);d=!0);}catch(i){e=!0,f=i}finally{try{!d&&h["return"]&&h["return"]()}finally{if(e)throw f}}return c}throw new TypeError("Invalid attempt to destructure non-iterable instance")},f=function(a){if(Array.isArray(a)){for(var b=0,c=Array(a.length);be;e++)d[e]=arguments[e];return b.forEach(function f(a,b,e){if(Array.isArray(a))return a.forEach(f);var g=c.indexOf(a);g>-1&&(e[b]=d[g])}),b=w(b),b=n.parseNumbers(b),b=p(b)}},registerOperator:function(a,b){j["default"][a]=b},registerConstant:function(a,b){l["default"][a]=b}},p=function(a){function b(b){return a.apply(this,arguments)}return b.toString=function(){return a.toString()},b}(function(a){return a.some(Array.isArray)?(a=a.map(function(a){return Array.isArray(a)?p(a):a}),p(a)):x(a)}),q=Object.keys(j["default"]).map(function(a){return j["default"][a].precedence}),r=Math.max.apply(Math,f(q)),s=Math.min.apply(Math,f(q)),t=function(a){for(var b=new h["default"](a),c=[],d="",e=void 0,f=void 0;b.next();)if(e=b.current(),f=c.length-1," "!==e)if(n.isNumber(e)||j["default"][e]||"."===e||"("===e||")"===e)if(d.length){var g=f-(d.length-1);B(d)&&n.isNumber(c[g])&&c.push("*"),c.push(d,e),d=""}else if(n.isNumber(c[f])&&(n.isNumber(e)||"."===e))c[f]+=e;else if("-"===c[f]){var i=c[f-1];j["default"][i]?c[f]+=e:")"===i?(c[f]="+",c.push("-"+e)):n.isNumber(i)?c.push(e):c[f]+=e}else c.push(e);else d+=e;if(d.length){var g=f-(d.length-1);B(d)&&n.isNumber(c[g])&&c.push("*"),c.push(d)}return u(c)},u=function(a){var b=0;return a.reduce(function(a,c){return c.indexOf("(")>-1?(c.length>1?n.dive(a,b).push(c.replace("(",""),[]):n.dive(a,b).push([]),b++):")"===c?b--:n.dive(a,b).push(c),a},[])},v=function(a){var b="string"==typeof a?j["default"][a]:a;if(!b)return null;var c=b.format.split("1"),d=c[0].length,e=c[1].length;return{left:d,right:e}},w=function(a){function b(b){return a.apply(this,arguments)}return b.toString=function(){return a.toString()},b}(function(a){var b=!0,c=!1,d=void 0;try{for(var f,g=a.entries()[Symbol.iterator]();!(b=(f=g.next()).done);b=!0){var h=e(f.value,2),i=h[0],k=h[1];Array.isArray(k)&&a.splice(i,1,w(k))}}catch(l){c=!0,d=l}finally{try{!b&&g["return"]&&g["return"]()}finally{if(c)throw d}}for(var m=s;r>=m;m++)for(var i=0;iu;u++)t=[t];i-=q}}return a}),x=function(a){var b,c=y(a);if(!c)return a[0];var d=v(c),e=d.left,g=a.slice(0,e),h=a.slice(e+1);return A((b=j["default"][c]).fn.apply(b,f(g).concat(f(h))))},y=function(a){var b=!0,c=!1,d=void 0;try{for(var e,f=a[Symbol.iterator]();!(b=(e=f.next()).done);b=!0){var g=e.value;if("string"==typeof g)return g}}catch(h){c=!0,d=h}finally{try{!b&&f["return"]&&f["return"]()}finally{if(c)throw d}}return null},z=function(a){return a.replace(/[A-Z]*/g,function(a){var b=l["default"][a];return b?"function"==typeof b?b():b:a})},A=function(a){return+a.toFixed(15)},B=function(a){return"string"==typeof a&&!n.isNumber(a)&&!j["default"][a]&&a===a.toLowerCase()};c.isVariable=B,c["default"]=o},{"./constants":1,"./helpers":2,"./operators":4,"./readstream":5}],4:[function(a,b,c){"use strict";Object.defineProperty(c,"__esModule",{value:!0}),c["default"]={"^":{fn:function(a,b){return Math.pow(a,b)},format:"010",precedence:0},"*":{fn:function(a,b){return a*b},format:"010",precedence:1},"/":{fn:function(a,b){return a/b},format:"010",precedence:1},"%":{fn:function(a,b){return a%b},format:"010",precedence:1},"\\":{fn:function(a,b){return Math.floor(a/b)},format:"010",precedence:1},"+":{fn:function(a,b){return a+b},format:"010",precedence:2},"-":{fn:function(a,b){return a-b},format:"010",precedence:2},"!":{fn:function(a){for(var b=1,c=0;a>c;++c)b*=c;return b},format:"01",precedence:2},log:{fn:Math.log,format:"10",precedence:-1},ln:{fn:Math.log,format:"10",precedence:-1},lg:{fn:function(a){return Math.log(a)/Math.log(2)},format:"10",precedence:-1},sin:{fn:Math.sin,format:"10",precedence:-1},cos:{fn:Math.cos,format:"10",precedence:-1},tan:{fn:Math.tan,format:"10",precedence:-1},cot:{fn:Math.cot,format:"10",precedence:-1},round:{fn:Math.round,format:"10",precedence:-1},floor:{fn:Math.floor,format:"10",precedence:-1}},b.exports=c["default"]},{}],5:[function(a,b,c){"use strict";Object.defineProperty(c,"__esModule",{value:!0}),c["default"]=function(a){var b=0,c=[];return{next:function(){return c.push(a[b]),b>=a.length?null:a[b++]},current:function(){return a[b-1]},index:function(){return b-1},to:function(c){var d="",e=b+c;for(b=b;e>b;++b)d+=[a[b]];return d},drain:function(){return c.splice(0,c.length)},replace:function(a){function b(b,c,d){return a.apply(this,arguments)}return b.toString=function(){return a.toString()},b}(function(c,d,e){var f=a.split("");f.splice(c,d,e),a=f.join(""),b-=d-c}),go:function(a){b+=a},all:function(){return a}}},b.exports=c["default"]},{}]},{},[3])(3)}); \ No newline at end of file