UNPKG

decimal-eval

Version:

A tiny, safe, fast JavaScript library for decimal arithmetic expressions.

3 lines (2 loc) 10.7 kB
!function(e,t){"object"==typeof exports&&"undefined"!=typeof module?t(exports):"function"==typeof define&&define.amd?define(["exports"],t):t((e="undefined"!=typeof globalThis?globalThis:e||self).DecimalEval={})}(this,(function(e){"use strict";function t(e,t){if(!(e instanceof t))throw new TypeError("Cannot call a class as a function")}function i(e,t){for(var i=0;i<t.length;i++){var n=t[i];n.enumerable=n.enumerable||!1,n.configurable=!0,"value"in n&&(n.writable=!0),Object.defineProperty(e,n.key,n)}}function n(e,t,i){return t in e?Object.defineProperty(e,t,{value:i,enumerable:!0,configurable:!0,writable:!0}):e[t]=i,e}var r=function e(i){var r,s=arguments.length>1&&void 0!==arguments[1]?arguments[1]:{};t(this,e),n(this,"label",void 0),n(this,"isBinary",void 0),n(this,"isPrefix",void 0),n(this,"precedence",void 0),n(this,"updateContext",void 0),this.label=i,this.isBinary=!!s.isBinary,this.isPrefix=!!s.isPrefix,this.precedence=null!==(r=s.precedence)&&void 0!==r?r:-1},s={start:new r("start"),end:new r("end"),parenL:new r("("),parenR:new r(")"),numeric:new r("numeric"),identifier:new r("identifier"),plus:new r("+",{isBinary:!0,precedence:13}),minus:new r("-",{isBinary:!0,precedence:13}),times:new r("*",{isBinary:!0,precedence:14}),div:new r("/",{isBinary:!0,precedence:14}),prefixPlus:new r("+",{isPrefix:!0,precedence:16}),prefixMinus:new r("-",{isPrefix:!0,precedence:16})};s.parenL.updateContext=function(){this.allowPrefix=!0},s.parenR.updateContext=function(){this.allowPrefix=!1},s.numeric.updateContext=function(){this.allowPrefix=!1},s.identifier.updateContext=function(){this.allowPrefix=!1};var o=function e(i){t(this,e),n(this,"type",void 0),n(this,"start",void 0),n(this,"end",void 0),this.type="",this.start=i,this.end=i};function a(e){return e>=48&&e<=57}function h(e){return 46===e||a(e)}function u(e){return e>=65&&e<=90||e>=97&&e<=122}function p(e){return!!u(e)||(!!a(e)||95===e)}var c=["+","-","*","/","(",")"],f=[];function d(e,t){if("string"!=typeof e||!/^\S+$/.test(e))throw new Error("The custom operator should be a non-empty string");if(c.includes(e))throw new Error("The custom operator cannot use reserved character, including: ".concat(c.join(", ")));if(h(e.charCodeAt(0)))throw new Error("The custom operator cannot start with a possible number, including: `.`, 0-9");if(63===e.charCodeAt(0))throw new Error("The custom operator cannot start with `?`");if(null!=t&&("number"!=typeof t||t<0))throw new Error("The precedence should be a number greater than 0")}var l=function e(i,s,o){var a=arguments.length>3&&void 0!==arguments[3]&&arguments[3];t(this,e),n(this,"value",void 0),n(this,"codes",void 0),n(this,"type",void 0),n(this,"calc",void 0),this.value=i,this.codes=i.split("").map((function(e,t){return i.charCodeAt(t)})),this.type=new r(i,{isBinary:!a,isPrefix:a,precedence:s}),this.calc=o};var v={"+":function(e,t){return String(Number(e)+Number(t))},"-":function(e,t){return String(Number(e)-Number(t))},"*":function(e,t){return String(Number(e)*Number(t))},"/":function(e,t){return String(Number(e)/Number(t))}};function y(e,t,i){switch(i){case"+":case"-":case"*":case"/":return v[i](e,t);default:for(var n=0;n<f.length;n++){var r=f[n];if(r.type.isBinary&&r.value===i)return r.calc(e,t)}}throw new Error("Unexpected binary operator: ".concat(i))}function x(e,t){switch(t){case"+":return e;case"-":return String(-e);default:for(var i=0;i<f.length;i++){var n=f[i];if(n.type.isPrefix&&n.value===t)return n.calc(e)}}throw new Error("Unexpected unary operator: ".concat(t))}function k(e){var t,i=arguments.length>1&&void 0!==arguments[1]?arguments[1]:{};if(e instanceof o)switch(e.type){case"Expression":return k(e.expression,i);case"BinaryExpression":return y(k(e.left,i),k(e.right,i),e.operator);case"UnaryExpression":return x(k(e.argument,i),e.operator);case"NumericLiteral":return e.value;case"Identifier":if(void 0===(t=i[e.name]))throw new Error("The scope name `".concat(e.name,"` is not initialized"));return String(t);default:throw new Error("Unexpected type: ".concat(e.type))}return e}var w=function(){function e(i){t(this,e),n(this,"input",void 0),n(this,"node",void 0),n(this,"pos",void 0),n(this,"tokenType",void 0),n(this,"value",void 0),n(this,"start",void 0),n(this,"end",void 0),n(this,"lastTokenStart",void 0),n(this,"lastTokenEnd",void 0),n(this,"allowPrefix",void 0),this.input=String(i),this.tokenType=s.start,this.value="",this.pos=0,this.start=0,this.end=0,this.lastTokenStart=0,this.lastTokenEnd=0,this.allowPrefix=!0}var r,c,d;return r=e,d=[{key:"evaluate",value:function(t,i){return new e(t).compile()(i)}}],(c=[{key:"compile",value:function(){var e=this.node;return void 0===e&&(e=this.parse()),function(t){return e?k(e,null!=t?t:{}):"0"}}},{key:"parse",value:function(){this.next();var e=this.startNode(this.start);return this.tokenType===s.end?this.node=null:(e.expression=this.parseExpression(),this.tokenType!==s.end&&this.unexpected(this.value),this.node=this.finishNode(e,"Expression"))}},{key:"parseExpression",value:function(){return this.parseExprAtom(this.start,-1)}},{key:"parseExprAtom",value:function(e,t){if(this.tokenType===s.parenL){this.next();var i=this.parseExprAtom(this.start,-1);return this.expect(s.parenR),this.parseExprOp(i,e,t)}var n=this.parseMaybeUnary(t);return this.parseExprOp(n,e,t)}},{key:"parseExprOp",value:function(e,t,i){var n=this.tokenType.precedence;if(this.tokenType.isBinary&&n>i){var r=this.startNode(t),s=this.value;this.next();var o=this.start,a=this.parseExprAtom(o,n),h=this.parseExprOp(a,o,n);return r.left=e,r.operator=s,r.right=h,this.finishNode(r,"BinaryExpression"),this.parseExprOp(r,t,i)}return e}},{key:"parseMaybeUnary",value:function(e){var t=this.tokenType.precedence,i=this.startNode(),n=this.start,r=this.value;if(this.tokenType.isPrefix&&t>=e)return i.operator=r,i.prefix=!0,this.next(),i.argument=this.parseExprAtom(this.start,t),this.finishNode(i,"UnaryExpression");if(this.tokenType===s.numeric){var o=function(e){for(var t=e,i=[],n=0;n<t.length;n++)95!==t.charCodeAt(n)&&i.push(t[n]);return i.length!==t.length&&(t=i.join("")),t}(r);return i.rawValue=r,i.value=o,this.next(),this.finishNode(i,"NumericLiteral")}return this.tokenType===s.identifier?(i.name=r,this.next(),this.finishNode(i,"Identifier")):this.unexpected(r,n)}},{key:"next",value:function(){if(this.lastTokenStart=this.start,this.lastTokenEnd=this.end,this.skipSpace(),this.start=this.pos,this.pos>=this.input.length){if(this.tokenType===s.end)return;this.finishToken(s.end)}else this.readToken()}},{key:"readToken",value:function(){return h(this.codeAt(this.pos))?this.readNumeric():this.readTokenFromCode()}},{key:"readNumeric",value:function(){for(var e=this.pos,t=-1,i=!0,n=!1,r=!1,o=-1;this.isValidPosition();){var h=this.codeAt(this.pos);if(a(h))-1===t&&(t=0),this.pos++,r=!1,n=!0;else{if(r){o=this.pos,r=!1;break}if(69===h||101===h){if(0!==t){o=this.pos;break}t++,this.pos++,!this.isValidPosition()||43!==this.codeAt(this.pos)&&45!==this.codeAt(this.pos)||this.pos++,i=!1,r=!0}else if(46===h){if(!i){o=this.pos;break}i=!1,this.pos++,this.pos-e==1&&(r=!0)}else{if(95!==h)break;if(!n){o=this.pos;break}n=!1,r=!0,this.pos++}}}r&&(o=this.pos-1),o>=0&&this.unexpected(this.input[o],o);var u=this.input.slice(e,this.pos);this.finishToken(s.numeric,u)}},{key:"readTokenFromCode",value:function(){var e,t,i,n=this.codeAt(this.pos);for(t=0;t<f.length;t++){var r=f[t];for(i=0;i<r.codes.length&&r.codes[i]===this.codeAt(this.pos+i);i++);if(i===r.codes.length){e=r;break}}if(e)return this.pos+=e.codes.length,this.finishToken(e.type,e.value);switch(n){case 40:return this.pos++,this.finishToken(s.parenL,"(");case 41:return this.pos++,this.finishToken(s.parenR,")");case 42:return this.pos++,this.finishToken(s.times,"*");case 43:return this.pos++,this.allowPrefix?this.finishToken(s.prefixPlus,"+"):this.finishToken(s.plus,"+");case 45:return this.pos++,this.allowPrefix?this.finishToken(s.prefixMinus,"-"):this.finishToken(s.minus,"-");case 47:return this.pos++,this.finishToken(s.div,"/");default:if(u(n))return this.readIdentifier()}this.unexpected(this.input[this.pos])}},{key:"readIdentifier",value:function(){for(var e=this.pos;this.isValidPosition()&&p(this.codeAt(this.pos));)this.pos++;var t=this.input.slice(e,this.pos);this.finishToken(s.identifier,t)}},{key:"finishToken",value:function(e){var t=arguments.length>1&&void 0!==arguments[1]?arguments[1]:"",i=this.tokenType;this.end=this.pos,this.tokenType=e,this.value=t,this.updateContext(i)}},{key:"updateContext",value:function(e){var t=this.tokenType;t.isBinary||t.isPrefix?this.allowPrefix=!0:t.updateContext&&t.updateContext.call(this,e)}},{key:"codeAt",value:function(e){return this.input.charCodeAt(e)}},{key:"isValidPosition",value:function(){return this.pos<this.input.length}},{key:"startNode",value:function(e){return new o(null!=e?e:this.start)}},{key:"finishNode",value:function(e,t){return e.type=t,e.end=this.lastTokenEnd,e}},{key:"skipSpace",value:function(){for(;this.isValidPosition();){var e=this.codeAt(this.pos);if(32===e||160===e)this.pos++;else if(13===e||10===e||8232===e||8233===e)13===e&&10===this.codeAt(this.pos+1)&&this.pos++,this.pos++;else{if(!(e>8&&e<14))break;this.pos++}}}},{key:"expect",value:function(e){this.eat(e)||this.unexpected(this.value)}},{key:"eat",value:function(e){return this.tokenType===e&&(this.next(),!0)}},{key:"unexpected",value:function(){var e=arguments.length>0&&void 0!==arguments[0]?arguments[0]:"",t=arguments.length>1?arguments[1]:void 0;this.raise(null!=t?t:this.start,"Unexpected token ".concat(e))}},{key:"raise",value:function(e,t){throw e>this.input.length-1?t="Unexpected end of input":t+=" at position ".concat(e),new SyntaxError(t)}}])&&i(r.prototype,c),d&&i(r,d),e}();n(w,"createBinaryOperator",void 0),n(w,"createUnaryOperator",void 0),n(w,"useOperator",void 0),n(w,"useAdapter",void 0),n(w,"Node",o),n(w,"TokenType",r),n(w,"tokenTypes",s),n(w,"installedOperators",f);var m=w.evaluate;w.createBinaryOperator=function(e,t,i){if(d(e,t),"function"!=typeof i)throw new Error("Expected to receive a calculation method, like: `(left, right) => String(left - right)`");return new l(e,t,i,!1)},w.createUnaryOperator=function(e,t,i){if(d(e,t),"function"!=typeof i)throw new Error("Expected to receive a calculation method, like: `(value) => String(Math.abs(value))`");return new l(e,t,i,!0)},w.useOperator=function(e){f.includes(e)||f.unshift(e)},w.useAdapter=function(e){e=e||{},["+","-","*","/"].forEach((function(t){if("function"!=typeof e[t])throw new Error("Missing method for calculation operator `".concat(t,"`"))})),v=e};var T={evaluate:m,Parser:w,Operator:l,version:"0.1.1"};e.Operator=l,e.Parser=w,e.default=T,e.evaluate=m,Object.defineProperty(e,"__esModule",{value:!0})})); //# sourceMappingURL=pure.min.js.map