Last active
November 13, 2016 15:10
-
-
Save think49/47fb5dcd29c552550a73192df6f1d947 to your computer and use it in GitHub Desktop.
eval-calculation-map-sample: Chironian さんのアドバイスを元に書いてみたコード。new Map(['value', '演算結果となる数値'], ['errors', [new SyntaxError('エラー1'), new SyntaxError('エラー2')]]) を返り値とする。
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>eval-calculation-map-sample.js</title> | |
<script> | |
/** | |
* eval-calculation-map-sample.js | |
* evaluate calculation formula. | |
* | |
* @version 0.1.1 | |
* @author think49 | |
* @url https://gist.github.com/think49/47fb5dcd29c552550a73192df6f1d947 | |
* @license http://www.opensource.org/licenses/mit-license.php (The MIT License) | |
*/ | |
var evalCalculation = (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 function evalCalculation (expression) { | |
var multiplyOrDivide = /(-?(?:\d+(?:\.\d+)?|\.\d+))([*/])(-?(?:\d+(?:\.\d+)?|\.\d+))/g, | |
addOrSubtract = /(-?(?:\d+(?:\.\d+)?|\.\d+))([+-])(-?(?:\d+(?:\.\d+)?|\.\d+))/g, | |
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])); | |
} | |
while (multiplyOrDivide.test(expression)) { | |
expression = expression.replace(multiplyOrDivide, calcDyadicOperator); | |
} | |
while (addOrSubtract.test(expression)) { | |
expression = expression.replace(addOrSubtract, calcDyadicOperator); | |
} | |
return new Map([['value', +expression], ['errors', errors]]); | |
}; | |
}(String, Math.pow, Math.max)); | |
</script> | |
</head> | |
<body> | |
<ul> | |
<li><a href="https://teratail.com/questions/54897#r88021">JavaScript - エラーメッセージをまとめて出力する為の最適解は?(54897)|teratail</a></li> | |
</ul> | |
<script> | |
'use strict'; | |
var map = evalCalculation('/1.1.1*'); | |
console.log(map.get('value')); // NaN | |
console.log(map.get('errors')); // [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 関連。
C++ の
std::map
について。TLS(Thread local storage) について。