This is an old thread, but I wrote this equation calculator, but it does not solve algebraic equations. However, there is a function that allows you to provide an array containing the assigned variables. But this does not solve for variables that do not have an assigned value.
I probably did not redo every script, but it seems to work pretty well.
Edit: This would need to be changed to handle negative numbers. Other than that ... works great.
Here is the fiddle
<!doctype html> <html> <head> <title>Javascript Equation Calculator</title> </head> <body> <input type="button" onclick="main()" value="calculate"><br> <input type="text" id="userinput"><br> <span id="result">Ready.</span><br> <script> function Calculator(){} String.prototype.replaceLast = function (what, replacement) { var pcs = this.split(what); var lastPc = pcs.pop(); return pcs.join(what) + replacement + lastPc; }; function inS(substr, str){return (str.indexOf(substr) > -1);} function arrayValueOrToken(arr, key, token) { if(key in arr) { return arr[key]; } return token; } function reduceEquation(inputStr) { console.log("reduceEquation Executed-----"); while(hasNest(inputStr)) { if(hasNest(inputStr)) { inputStr = inputStr.replace(")(",')*('); for(var i=0;i<=9;i++) { inputStr = inputStr.replace(i+"(",i+'*('); inputStr = inputStr.replace(")"+i,')*'+i); } var s = inputStr.lastIndexOf("("); var e = 0; for(i=s;i,inputStr.length;i++){if(inputStr[i]==")"){e=i+1;break;}} var eq = inputStr.substring(s,e); var replace = eq; eq = eq.replace(/[()]/g, ''); var substitution = solveEquation(eq); inputStr = inputStr.replaceLast(replace,substitution); } } return inputStr; } function solveEquation(eq) { console.log("solveEquation Executed-----"); eq = doFirstOrder(eq); eq = doLastOrder(eq); return eq; } function doFirstOrder(eq) { console.log("doFirstOrder Executed-----"); for(var i=0;i<eq.length;i++) { if(eq[i]=="*"){eq = solve(eq,"*");return doFirstOrder(eq);} if(eq[i]=='/'){eq = solve(eq,'/');return doFirstOrder(eq);} } return eq; } function doLastOrder(eq) { console.log("doLastOrder Executed-----"); for(var i=0;i<eq.length;i++) { if(eq[i]=="+"){eq = solve(eq,"+");return doLastOrder(eq);} if(eq[i]=="-"){eq = solve(eq,"-");return doLastOrder(eq);} } return eq; } function solve(eq, operator) { var setOp = operator; console.log("solve Executed-----"); var buildEq = "",var1 = true,done = false,char=""; var operators = "+-/*"; var ops = operators.replace(operator, '').split(''); var a=ops[0]; var b=ops[1]; var c=ops[2]; for(var i=0;i<eq.length;i++) { char = eq[i]; switch(true) { case(char==operator):if(var1===true){var1 = false;}else{done = true;}break; case(char==a): case(char==b): case(char==c):if(var1){char = ""; buildEq = "";}else{done = true;} } if(done){break;} buildEq = buildEq + char; } var parts = parts = buildEq.split(operator); var solution = null; if(operator=="+"){solution = parseFloat(parts[0]) + parseFloat(parts[1]);} if(operator=="-"){solution = parseFloat(parts[0]) - parseFloat(parts[1]);} if(operator=="*"){solution = parseFloat(parts[0]) * parseFloat(parts[1]);} if(operator=="/"){solution = parseFloat(parts[0]) / parseFloat(parts[1]);} return eq.replace(buildEq, solution); } function hasNest(inputStr){return inS("(",inputStr);} function allNestsComplete(inputStr) { var oC = 0, cC = 0,char=""; for(var i=0;i<inputStr.length;i++){char = inputStr[i];if(char=="("){oC+=1;}if(char==")"){cC+=1;}} return (oC==cC); } Calculator.prototype.calc = function(inputStr) { console.log("Calc Executed-----"); inputStr = inputStr.replace(/ /g, ""); inputStr = inputStr.replace(/\\/g, '/'); inputStr = inputStr.replace(/x/g, "*") inputStr = inputStr.replace(/X/g, "*") if(!allNestsComplete(inputStr)){return "Nested operations not opened/closed properly.";} inputStr=reduceEquation(inputStr); inputStr = solveEquation(inputStr); return inputStr; }; Calculator.prototype.calcWithVars = function(inputList) { if(inputList.length < 2){return "One or more missing arguments!";} var vars = []; var assocVars = []; var lastVarIndex = inputList.length - 2; var i = 0; var inputStr = inputList[inputList.length-1]; for(i=0;i<=lastVarIndex;i++) { vars.push(inputList[i].replace(/ /g, "")); } for(i=0;i<=vars.length-1;i++) { var vParts = vars[i].split("="); var vName = vParts[0]; var vValue = vParts[1]; assocVars[vName] = vValue; } inputStr = inputStr.replace(/ /g, ""); var eqVars = inputStr.replace(/\s+/g, ' ').replace(/[^a-zA-Z-]/g, ' ').replace(/\s\s+/g, ' '); if(inS(" ", eqVars)) { eqVars = eqVars.split(" "); } else{eqVars = [eqVars];} eqVars.sort(function(a, b){return a.length - a.length;}); var tempTokens = []; var tempCount = 1; for(i=0;i<eqVars.length;i++) { var eqVname = eqVars[i]; var substitution = arrayValueOrToken(assocVars, eqVname, "<unknown>"); if(substitution != "<unknown>") { inputStr = inputStr.replace(eqVname,substitution); } else { var tempToken = "#______#"+tempCount+"#______#"; tempCount++; tempTokens.push(tempToken + "?" + eqVname); inputStr = inputStr.replace(eqVname,tempToken); } } for(i=0;i<tempTokens.length;i++) { var tokenSet = tempTokens[i]; var tokenParts = tokenSet.split("?"); var token = tokenParts[0]; var variableName = tokenParts[1]; inputStr = inputStr.replace(token,variableName); } var answerName = "<unknown>"; var eq = inputStr; if(inS("=", inputStr)) { var eqParts = inputStr.split("="); answerName = eqParts[0]; eq = eqParts[1]; } eq = this.calc(eq); var result = []; for(i=0;i<eqVars.length;i++) { var v = arrayValueOrToken(assocVars, eqVars[i], "<unknown>"); if(v != "<unknown>") { result.push(assocVars[eqVars[i]]); } } result.push(eq); return result; }; function main() { var calculator = new Calculator(); elUserInput = document.getElementById('userinput'); console.log("input: "+ elUserInput.value); elResult = document.getElementById('result'); equation = elUserInput.value; result = calculator.calc(equation); console.log("result: "+ result); elResult.innerHTML = result; } </script> </body> </html>