Skip to content

Instantly share code, notes, and snippets.

@gkucmierz
Created October 18, 2016 02:53
Show Gist options
  • Select an option

  • Save gkucmierz/04967642d6b2b045ec8988a9d847603d to your computer and use it in GitHub Desktop.

Select an option

Save gkucmierz/04967642d6b2b045ec8988a9d847603d to your computer and use it in GitHub Desktop.
Calculate Mathematical Expression
let resolve = (tokens, vars) => {
let getVal = (t, vars) => {
if (isIdent(t)) {
if (t in vars) return +vars[t];
throw Error(`variable ${t} is not defined`);
}
return +t;
};
let isOp = (str) => op.s.indexOf(str) !== -1;
let isIdent = (str) => !!str.match(/^[a-z_][a-z_\d]*$/i);
let opSt = (fn) => {
return (t, i, vars) => {
let res = fn(getVal(t[i-1], vars), getVal(t[i+1], vars));
t.splice(i - 1, 3, `${res}`)
return -1;
};
};
let = op = {
s: '(*/%+-=',
p: [0, 1, 1, 1, 2, 2, 3],
fn: [
(t, i, vars) => {
let c = 0;
let idx = t.findIndex((t, ii) => {
if (ii < i) return false;
c += ({ '(': 1, ')': -1 })[t] || 0;
return c === 0;
});
let res = resolve(t.slice(i+1, idx), vars);
t.splice(i, idx - i + 1, `${res}`);
return 0;
},
opSt((a, b) => a * b),
opSt((a, b) => a / b),
opSt((a, b) => a % b),
opSt((a, b) => a + b),
opSt((a, b) => a - b),
(t, i, vars) => {
vars[t[i-1]] = t[i+1];
tokens.splice(i - 1, 3, t[i+1]);
return -1;
}
]
};
let maxP = Math.max(...op.p);
for (let p = 0; p <= maxP; ++p) {
for (let i = 0; i < tokens.length; ++i) {
if (isIdent(tokens[i])) {
if (tokens[i] in vars) {
tokens[i] = vars[tokens[i]];
}
}
if (isOp(tokens[i])) {
let idx = op.s.indexOf(tokens[i]);
if (op.p[idx] === p) {
i += op.fn[idx](tokens, i, vars);
}
}
}
}
return getVal(tokens[0]);
};
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment