PeterCanessa Oh Posted January 16, 2012 Share Posted January 16, 2012 I recently posted a routine to evaluate expression written in Postfix (reverse Polish notation). This one is better in that it doesn't have a separate Stack list. It is simpler, but slightly less efficient, in handling values as it tests them all to see if they're constants. Since I don't expect this routine to have heavy-duty use the simplicity and symmetry with the operator-handling seemed preferable. float EvalPostfix(string Expr){ // Evaluates string expressions written in reverse Polish notation (postfix) // PeterCanessa Oh // NB: All operands and operators must be space-delimited, all operators are binary // Supports operators +, -, *, /, % (mod) and ^ (exponentiation) and constants e, Phi and Pi list Parts = llParseString2List(Expr, [" ", " "], []); integer Pointer; while(Pointer < llGetListLength(Parts)){ Expr = llToUpper(llList2String(Parts, Pointer)); if(-1 != llListFindList(["+", "-", "*", "/", "%", "^"], [Expr])){ // Operator if(1 < Pointer){ if("+" == Expr){ Parts = llListReplaceList(Parts, [((float) llList2String(Parts, Pointer - 2)) + ((float) llList2String(Parts, Pointer - 1))], Pointer - 2, Pointer); }else if("-" == Expr){ Parts = llListReplaceList(Parts, [((float) llList2String(Parts, Pointer - 2)) - ((float) llList2String(Parts, Pointer - 1))], Pointer - 2, Pointer); }else if("*" == Expr){ Parts = llListReplaceList(Parts, [((float) llList2String(Parts, Pointer - 2)) * ((float) llList2String(Parts, Pointer - 1))], Pointer - 2, Pointer); }else if("/" == Expr){ if((float) llList2String(Parts, Pointer - 1)){ Parts = llListReplaceList(Parts, [((float) llList2String(Parts, Pointer - 2)) / ((float) llList2String(Parts, Pointer - 1))], Pointer - 2, Pointer); }else{ // Division by zero error, just return zero Parts = [0.0]; Pointer = 2; } }else if("%" == Expr){ Parts = llListReplaceList(Parts, [((integer) llList2String(Parts, Pointer - 2)) % ((integer) llList2String(Parts, Pointer - 1))], Pointer - 2, Pointer); }else if("^" == Expr){ Parts = llListReplaceList(Parts, [llPow(((float) llList2String(Parts, Pointer - 2)), ((float) llList2String(Parts, Pointer - 1)))], Pointer - 2, Pointer); } Pointer--; // <-- As we've reduced the input list by 2 this is actually the 'next' element }else{ // Stack error - there aren't enough operands for the operator to use so just return zero Parts = [0.0]; Pointer++; } }else{ // Translate constants if("E" == Expr){ llListReplaceList(Parts, ["2.7182817"], Pointer, Pointer); }else if("PHI" == Expr){ llListReplaceList(Parts, ["1.618034"], Pointer, Pointer); }else if("PI" == Expr){ llListReplaceList(Parts, ["3.1415927"], Pointer, Pointer); } // Otherwise it's a value that doesn't need translating or a mistake that will take the value 0.0 anyway Pointer++; } } if(1 != llGetListLength(Parts)){ // Parse error; there should only be a single entry, the result, left on the stack if the expression was properly formed so just return zero return 0.0; } // Return the final result return (float) llList2String(Parts, 0); } default{ state_entry(){ llOwnerSay("Infix (or anything else) '2' = " + (string) EvalPostfix("2")); llOwnerSay("Infix 3 + 4 = " + (string) EvalPostfix("3 4 +")); llOwnerSay("Infix 2 + 3 / 6 - 4 (assuming strict L To R calculation) = " + (string) EvalPostfix("2 3 + 6 / 4 -")); llOwnerSay("Infix (2 + 3) / (6 - 4) = " + (string) EvalPostfix("2 3 + 6 4 - /")); } } Link to comment Share on other sites More sharing options...
Recommended Posts
Please take a moment to consider if this thread is worth bumping.
Please sign in to comment
You will be able to leave a comment after signing in
Sign In Now