**Calculator for user input of Math expression**

ericlin@ms1.hinet.net

If user inputs a string of math expression that is mixed with operator and numbers, "3+5+7", how do we get the value ?

I introduced a method using getURL to pass the expression to javascript of
browser and browser will calculate the result. Here we are going to do it
completely in Flash.

The process is called "parsing". We will take apart numbers and
operators, then reassembly numbers according to operators we found.

First, we take the input string to see whether it is a number without operators, such as "98". If not, we scan the string for an operator and split the string into format of (substring1 - operator - substring2); And then do calculation. For example "9+8" will be split into ("9", "+","8"), and then we do (9+8). If it is not a number, nor operators found, then we say it is invalid. For example "9B". Here we begin with operator "+".

function getValue(myString) {

var value = Number(myString);

if (!isNaN(value)) {

return value;

}

//--------------------------------------------

//for "+"

var k = myString.lastIndexOf("+");

if (k>0) {

var substr1 = myString.substr(0, k);

var substr2 = myString.substr(k+1, myString.length-k-1);

var number1 = Number(substr1);

var number2 = Number(substr2);

return (number1+number2);

}

//-------------------------------------------

return NaN;

}

This is the basis of parsing. What the function does is : If there is a "+" in the string, we get number1 and number2 and add them together.

However, if our string is something like :"3+5+7", the first substring is "3+5", the second substring is "7"; how can we get the correct number of ("3+5") ?

Since substring1 and substring2 may be still a mixture of number and expression, we need a way to get the number of an expression like ("3+5"); But, we already have that function, right ? That function is this function. So, we replace "var number1=Number(substr1);" with "var number1=getValue(substr1);"

function getValue(myString) {

var value = Number(myString);

if (!isNaN(value)) {

return value;

}

//--------------------------------------------

//for "+"

var k = myString.lastIndexOf("+");

if (k>0) {

var substr1 = myString.substr(0, k);

var substr2 = myString.substr(k+1, myString.length-k-1);

var number1 = getValue(substr1);

var number2 = getValue(substr2);

return (number1+number2);

}

//-------------------------------------------

return NaN;

}

trace(getValue("3+5+7+9"));

This is a "recursive" function. A function calls itself. It is common to
get an infinite loop when we try to write a recursive function. We got to be
careful to check for proper ending of the loop. It is safe for the codes I wrote
above.

That is all we need to get the value of this string "3+5+8"; We can test "5+6+8+20+89", it will successfully handle string with only "+" operation;

The next step is to extend our function to handle other operators such as "-*/^". The script is nearly the same as the way we do for "+". Scan the string to find specific operators, if found, do calculation as above. For example, for "-",
we copy that block and paste below, change the line: __ var k =
myString.lastIndexOf("+");__ into __var k =
myString.lastIndexOf("-");__ And change the line: __return (number1+number2);__
into __return (number1*number2);__

Two things should be mentioned. We must use "lastIndexOf" when parsing. Dont use "indexOf". The second point is the priority order. We need to put "+","-" blocks before "*" and "/" blocks. This is the rule for Math. We should not break "3+5*7-9" into "3+5" ,"*", "7-9".

Here I suggest you do write script to extend the function to handle "+-*/" and make a movie and test a string like "3+5*7/8+9-11"; It should work well.

It is more complex to handle parenthesis and functions. But, what we need is just adding a block of (if then) statement; For parenthesis, We search for last appearnce of ( , then from there we search for the first appearance of );

Here we should tell it is a pure parenthesis like "3+(5-7)*9", or a parenthesis of a function, like "2+abs(6-8)"; The rule is that: From the (, we search for operators backward. If there is something between operators and "(", then it is function, the string in the parenthesis is the arguments of that function. Otherwise, it is a pure parenthesis that affects the priority of calculation only.

Now we add codes that handles pure parenthesis. We are not going to discuss the "function" part. If you know these script well, I believe you can handle functions by yourself.

OK, we found "(" and ")". Then we cut out the substring between them. We get the value of that substring and joint them together before continue. This is for pure parenthesis. It should be put in the first block before operators block.

//for parenthesis

var k = myString.lastIndexOf("(");

var m = myString.indexOf(")", k);

if (k>0) {

var substr1=myString.substr(0, k);

var substr2=myString.substr(k+1, m-k-1);

var substr3=myString.substr(m+1, myString.length-m-1);

var ParenthesisValue = getValue(substr2);

var newStr = (substr1+parenthesisValue+substr3);

return getValue(newStr);

}

Here, "3-(5+7)*9" will be split into "3+", "5+7" , "*9"; And we try getValue of "5+7", the result is 12; The we joint them together: "3+", "12", "*9" will be "3+12*9".

That is all we need to get a value from a string of math expression. You can stop here and try to make your movie now.

If we would include X in it, like X=8; What is the value of "56*X-7/(4-*X)", then we just search X and replace it by 8, and pass this string to that function. We will discuss in later session about the other way to do this. That is more complex.