JSFiddle - React, Tailwind, and code Playground
HTML
<input type="text" id="userInput" />
<input type="button" value="Calculate" id="calculate" />
<div id="result"></div>
JavaScript
function* tokenize(s) {
// --- Parse a calculation string into an sequence of numbers and operators
let token = "";
for (const character of s.slice(0, -1)) {
if ("^*/+-".includes(character) && token !== "") {
yield parseFloat(token);
yield character;
token = "";
} else {
token += character;
}
}
yield parseFloat(token + s.at(-1));
}
function calculateOperators(tokens, operators) {
const r = [];
let operator;
for (const token of tokens) {
if (token in operators) {
operator = operators[token];
} else if (operator) {
r[r.length - 1] = operator(r[r.length - 1], token);
operator = null;
} else {
r.push(token);
}
}
return r;
}
function calculate(tokens) {
// --- Perform a calculation expressed as a sequence of operators and numbers
const precedence = [{
'^': (a, b) => Math.pow(a, b)
},
{
'*': (a, b) => a * b,
'/': (a, b) => a / b
},
{
'+': (a, b) => a + b,
'-': (a, b) => a - b
}
];
tokens = precedence.reduce(calculateOperators, tokens);
if (tokens.length === 1) {
return tokens[0];
} else {
throw new Error(`Unable to resolve calculation ${tokens}`);
}
}
const calculateButton = document.getElementById('calculate');
const userInput = document.getElementById('userInput');
const result = document.getElementById('result');
calculateButton.addEventListener('click', function() {
result.innerHTML = "The answer is " + calculate(tokenize(userInput.value));
});