Reputation: 377
Why am I getting a RangeError: Maximum call stack exceeded
error? I am trying to parse through text to find math and solve it. It was working until I started to implement parenthesis'. I have tried to find the error but I just can't figure it out.
My Code:
var alg = {
calc: function(eq, solveFor) {
var out;
var sideOne = eq.substring(0, eq.indexOf('='))
var sideTwo = eq.substring(eq.indexOf('=') + 1)
if (sideOne === solveFor) {
alg.simplify(sideTwo);
}
if (sideTwo === solveFor) {
alg.simplify(sideOne);
}
},
simplify: function(eq) {
str = $.trim(eq);
if (str == undefined) {
console.error('Error: null string')
} else {
var charMatch = /^[\d\*\/\+\-\^\(\) ]+$/
if (charMatch.exec(str) === null) {
console.error('Error: Invalid char/expression')
} else {
alg.parMath('not');
alg.expRoot(solve);
alg.multDiv(solve);
alg.addSubtr(solve);
}
}
},
fromPar: function(par) {
alg.parMath(par);
alg.expRoot(solve);
alg.multDiv(solve);
alg.addSubtr(solve);
},
parMath: function(source) {
var reP = /\(([\d\*\/\+\-\^\(\) ]+)\)/
var exP = reP.exec(str)
if (source === 'par') {
str = str.replace(exP[0], solve)
}
if (exP !== null) {
use = 'par'
solve = exP[1]
} else {
use = 'not'
solve = str;
}
},
expRoot: function() {
var fracCon = /(\d+)\/(\d+)/
var reER = /(\d+)(\^)(\d+(\/\d)?)(?!\/)/
var exER = reER.exec(solve)
if (exER !== null) {
var exFC = fracCon.exec(exER[3])
if (exFC !== null) {
var rep = Math.pow(parseFloat(exER[1]),(parseFloat(exFC[1]) / parseFloat(exFC[2])))
} else {
var rep = Math.pow(parseFloat(exER[1]),parseFloat(exER[3]))
}
solve = solve.replace(exER[0], rep)
if (reER.exec(solve) !== null) {
alg.expRoot();
}
}
},
multDiv: function() {
var reMD = /(\d+(?:\.\d+)?) *([\*|\/]) *(\d+(?:\.\d+)?)/
var exMD = reMD.exec(solve);
if (exMD !== null) {
if (exMD[2] === "*") {
var rep = parseFloat(exMD[1]) * parseFloat(exMD[3]);
var rep = Math.round(rep * 1000000) / 1000000;
} else {
var rep = parseFloat(exMD[1]) / parseFloat(exMD[3]);
var rep = Math.round(rep * 1000000) / 1000000;
}
if (use !== 'par') {
solve = solve.replace(exMD[0], rep);
}
if (reMD.exec(solve) !== null) {
alg.multDiv();
}
}
},
addSubtr: function() {
var reAS = /(\d+(?:\.\d+)?) *([\+|\-]) *(\d+(?:\.\d+)?)/
var exAS = reAS.exec(solve); //Getting RangeError here
if (exAS !== null) {
if (exAS[2] === "+") {
var rep = parseFloat(exAS[1]) + parseFloat(exAS[3])
var rep = Math.round(rep * 1000000) / 1000000
} else {
var rep = parseFloat(exAS[1]) - parseFloat(exAS[3])
var rep = Math.round(rep * 1000000) / 1000000
}
if (use !== 'par') {
str = str.replace(exAS[0], rep)
}
if (exAS !== null) {
alg.addSubtr(solve);
} else {
if (use == 'not') {
out = solve;
} else {
alg.fromPar('par')
}
}
} else {
if (use == 'not') {
out = solve;
} else {
alg.fromPar('par')
}
}
}
};
console.log(alg.calc('x=(1+1)', "x"));
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
I'm getting the error at the start of addSubtr
function (marked by a comment). Can anyone help me find how to fix the error?
Upvotes: 1
Views: 42
Reputation: 3987
Your main problem is that you have an infinite loop which is here
if (exAS !== null) {
alg.addSubtr(solve);
}
This is a useless check for two reasons. One because as you notcie exAS is defined in addSubtr. So every time you call this function you are resetting the value.
Your other problems are you are create variables with the same names, and relying off of static variables/ void functions.
If pm me i cant help you workout the correct way to structure this this function and all the other functions .
Upvotes: 0
Reputation: 29086
The problem is that your code goes into an infinite loop. Here is the relevant part of the logic
addSubtr: function() {
/* ommitted */
var exAS = reAS.exec(solve); //Getting RangeError here
if (exAS !== null) {
/* ommitted - logic here*/
if (exAS !== null) {
alg.addSubtr(solve);
/* ommitted */
}
}
}
exAS
by parsing solve
through a regex. if
condition and do some logicif
statement that checks if the regex matched anything. Now, by definition, this would be true - it can be easily seen with a lot of code removed - the same condition is checked for twice. There is nothing that would change the the outcome between the two if
s.Because the input is the same, the logic will work the same so steps 1-5 are executed again and the function is called again.
This causes infinite recursion. Well, in reality there is a limit and that's the stack size for JavaScript, which is why you are getting the error. It's a bit misleading, since it's the regex that runs over the call stack size, not the recursive call to addSubtr
, else it would have been a bit more clear what is going on.
For how to fix it - you need to restructure the logic so you don't get into infinite loops. I am not sure exactly what is the best way for your case but I'd suggest working it out yourself - it would be a useful exercise regardless. Here are some pointers
In point 4.
I made, I mentioned that there was an essentially useless check. I assume that it is supposed to be useful.
- You may have intended the inner if
to be outside of the outer one. As it stands now, the two are equivalent so the inner if
can just be removed.
- maybe the condition of the inner if
is incorrect - it could be that you only sometimes want to do the recursive call, not every time.
- perhaps there was supposed to be something that changes either exAS
or solve
or both. Thus either the condition would (potentially) yield a different result the second time it's checked, or the function would produce a different result when called recursively (which would make the recursive call useful) or both.
Upvotes: 1