Skip to content

Instantly share code, notes, and snippets.

@ndugger
Last active August 19, 2017 19:11
Show Gist options
  • Save ndugger/d240f668436a6ba5edbb4612114d9f05 to your computer and use it in GitHub Desktop.
Save ndugger/d240f668436a6ba5edbb4612114d9f05 to your computer and use it in GitHub Desktop.
function arithmetic (input) {
let expression = input.replace(/\s/g, '');
const numbers = /((?:\d|\.)+)/;
const groups = /\(([^(]+?)\)/;
const methods = [
{ op: /(\^|\*{2})/, fn: (x, o, y) => x ** y },
{ op: /(\*|\/|\%)/, fn: (x, o, y) => {
if (o === '*') return x * y;
if (o === '/') return x / y;
if (o === '%') return x % y;
} },
{ op: /(\+|\-)/, fn: (x, o, y) => {
if (o === '+') return x + y;
if (o === '-') return x - y;
} }
];
const evaluate = terms => {
for (const { op, fn } of methods) {
const regex = new RegExp(numbers.source + op.source + numbers.source);
while (terms.match(regex)) {
const [ term, x, o, y ] = terms.match(regex);
terms = terms.replace(term, fn(Number(x), o, Number(y)));
}
}
return terms;
}
const negative = new RegExp(`(?:(^)|${ methods.map(m => m.op.source).join('|') })\-${ numbers.source }`);
while (expression.match(negative)) {
const [ term ] = expression.match(negative);
expression = expression.replace(term, `(0${ term })`);
}
while (expression.match(groups)) {
const [ group, terms ] = expression.match(groups);
expression = expression.replace(group, evaluate(terms));
}
return Number(evaluate(expression));
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment