Last active
November 13, 2016 15:53
-
-
Save think49/3c484937a84c91cd5c51f5788c7c34c7 to your computer and use it in GitHub Desktop.
calculation-sample.js: LLmanさんのアドバイスを元に書いたコード。SyntaxErrorのエラー検出処理と数値演算処理を別関数に分割した。
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<!DOCTYPE html> | |
<html> | |
<head> | |
<meta charset="UTF-8" /> | |
<title>calculation-sample.js</title> | |
<script> | |
/** | |
* calculation-sample.js | |
* evaluate calculation formula. | |
* | |
* @version 0.1.1 | |
* @author think49 | |
* @url https://gist.github.com/think49/3c484937a84c91cd5c51f5788c7c34c7 | |
* @license http://www.opensource.org/licenses/mit-license.php (The MIT License) | |
*/ | |
'use strict'; | |
var Calculation = (function (String, pow, max) { | |
'use strict'; | |
function getDecimalPartLength (numberString) { | |
var result = /\.\d+$/.exec(numberString); | |
return result ? result[0].length - 1 : 0; | |
} | |
function calcDyadicOperator (matched, number1, operator, number2) { | |
var decimalPart = /\.\d+$/, powerNumber1, powerNumber2, result; | |
switch (operator) { | |
case '+': | |
powerNumber1 = pow(10, max(getDecimalPartLength(number1), getDecimalPartLength(number2))); | |
result = (powerNumber1 * number1 + powerNumber1 * number2) / powerNumber1; | |
break; | |
case '-': | |
powerNumber1 = pow(10, max(getDecimalPartLength(number1), getDecimalPartLength(number2))); | |
result = (powerNumber1 * number1 - powerNumber1 * number2) / powerNumber1; | |
break; | |
case '*': | |
powerNumber1 = pow(10, getDecimalPartLength(number1)); | |
powerNumber2 = pow(10, getDecimalPartLength(number2)); | |
result = (number1 * powerNumber1) * (number2 * powerNumber2) / (powerNumber1 * powerNumber2); | |
break; | |
case '/': | |
powerNumber1 = pow(10, max(getDecimalPartLength(number1), getDecimalPartLength(number2))); | |
result = (number1 * powerNumber1) / (number2 * powerNumber1); | |
break; | |
default: | |
console.warn('expression: ' + number1 + operator + number2); | |
throw new Error(operator + ' is not a operator'); | |
} | |
// console.log(String(number1) + operator + number2 + '=' + result); | |
return result; | |
} | |
return { | |
eval: function _eval (expression) { | |
var multiplyOrDivide = /(-?(?:\d+(?:\.\d+)?|\.\d+))([*/])(-?(?:\d+(?:\.\d+)?|\.\d+))/g, | |
addOrSubtract = /(-?(?:\d+(?:\.\d+)?|\.\d+))([+-])(-?(?:\d+(?:\.\d+)?|\.\d+))/g; | |
while (multiplyOrDivide.test(expression)) { | |
expression = expression.replace(multiplyOrDivide, calcDyadicOperator); | |
} | |
while (addOrSubtract.test(expression)) { | |
expression = expression.replace(addOrSubtract, calcDyadicOperator); | |
} | |
return +expression; | |
}, | |
checkSyntax: function checkSyntax (expression) { | |
var errors = [], illegalString; | |
expression = String(expression).replace(/\s+/g, ''); | |
if (illegalString = /^[+-]?(?:\.[^\d]|[^\d.+-])/.exec(expression)) { | |
errors.push(new SyntaxError('An expression starts with an unexpected token: ' + illegalString[0])); | |
} | |
if (illegalString = /[^\d]$/.exec(expression)) { | |
errors.push(new SyntaxError('An expression ends with an unexpected token: ' + illegalString[0])); | |
} | |
if (illegalString = /\d*(?:\.\d*){2,}/.exec(expression)) { | |
errors.push(new SyntaxError('Illegal number: ' + illegalString[0])); | |
} | |
return errors; | |
} | |
}; | |
}(String, Math.pow, Math.max)); | |
</script> | |
</head> | |
<body> | |
<ul> | |
<li><a href="https://teratail.com/questions/54897#r88052">JavaScript - エラーメッセージをまとめて出力する為の最適解は?(54897)|teratail</a></li> | |
</ul> | |
<script> | |
'use strict'; | |
console.log(Calculation.eval('/1.1.1*')); // NaN | |
console.log(Calculation.checkSyntax('/1.1.1*')); // [new SyntaxError('An expression starts with an unexpected token: /'), new SyntaxError('An expression ends with an unexpected token: *'), new SyntaxError('Illegal number: 1.1.1')] | |
</script> | |
</body> | |
</html> |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
eval-calculation.js 関連。