/* 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!= */