RosettaCodeData/Task/Arithmetic-evaluation/Jsish/arithmetic-evaluation.jsish

78 lines
2.2 KiB
Plaintext

/* Arithmetic evaluation, in Jsish */
function evalArithmeticExp(s) {
s = s.replace(/\s/g,'').replace(/^\+/,'');
var rePara = /\([^\(\)]*\)/;
var exp;
function evalExp(s) {
s = s.replace(/[\(\)]/g,'');
var reMD = /[0-9]+\.?[0-9]*\s*[\*\/]\s*[+-]?[0-9]+\.?[0-9]*/;
var reM = /\*/;
var reAS = /-?[0-9]+\.?[0-9]*\s*[\+-]\s*[+-]?[0-9]+\.?[0-9]*/;
var reA = /[0-9]\+/;
var exp;
function multiply(s, b=0) {
b = s.split('*');
return b[0] * b[1];
}
function divide(s, b=0) {
b = s.split('/');
return b[0] / b[1];
}
function add(s, b=0) {
s = s.replace(/^\+/,'').replace(/\++/,'+');
b = s.split('+');
return Number(b[0]) + Number(b[1]);
}
function subtract(s, b=0) {
s = s.replace(/\+-|-\+/g,'-');
if (s.match(/--/)) {
return add(s.replace(/--/,'+'));
}
b = s.split('-');
return b.length == 3 ? -1 * b[1] - b[2] : b[0] - b[1];
}
while (exp = s.match(reMD)) {
s = exp[0].match(reM) ? s.replace(exp[0], multiply(exp[0]).toString()) : s.replace(exp[0], divide(exp[0]).toString());
}
while (exp = s.match(reAS)) {
s = exp[0].match(reA)? s.replace(exp[0], add(exp[0]).toString()) : s.replace(exp[0], subtract(exp[0]).toString());
}
return '' + s;
}
while (exp = s.match(rePara)) {
s = s.replace(exp[0], evalExp(exp[0]));
}
return evalExp(s);
}
if (Interp.conf('unitTest')) {
; evalArithmeticExp('2+3');
; evalArithmeticExp('2+3/4');
; evalArithmeticExp('2*3-4');
; evalArithmeticExp('2*(3+4)+5/6');
; evalArithmeticExp('2 * (3 + (4 * 5 + (6 * 7) * 8) - 9) * 10');
; evalArithmeticExp('2*-3--4+-0.25');
}
/*
=!EXPECTSTART!=
evalArithmeticExp('2+3') ==> 5
evalArithmeticExp('2+3/4') ==> 2.75
evalArithmeticExp('2*3-4') ==> 2
evalArithmeticExp('2*(3+4)+5/6') ==> 14.8333333333333
evalArithmeticExp('2 * (3 + (4 * 5 + (6 * 7) * 8) - 9) * 10') ==> 7000
evalArithmeticExp('2*-3--4+-0.25') ==> -2.25
=!EXPECTEND!=
*/