/// <summary>Evaluates the specified sym1.</summary> /// <param name="sym1">The sym1.</param> /// <param name="opr">The opr.</param> /// <param name="sym2">The sym2.</param> /// <returns></returns> protected Symbol Evaluate(Symbol sym1, Symbol opr, Symbol sym2) { Symbol result; result.m_name = sym1.m_name + opr.m_name + sym2.m_name; result.m_type = ExpressionType.Result; result.m_value = 0; result.m_values = null; switch (opr.m_name) { case "^": result.m_value = System.Math.Pow(sym1.m_value, sym2.m_value); break; case "/": { if (sym1.m_values != null && sym2.m_values != null) result.m_values = MathUtilities.Divide(sym1.m_values, sym2.m_values); else { if (sym2.m_value > 0) result.m_value = sym1.m_value / sym2.m_value; else { result.m_name = "Divide by Zero."; result.m_type = ExpressionType.Error; } } break; } case "*": if (sym1.m_values != null && sym2.m_values != null) result.m_values = MathUtilities.Multiply(sym1.m_values, sym2.m_values); else result.m_value = sym1.m_value * sym2.m_value; break; case "%": result.m_value = sym1.m_value % sym2.m_value; break; case "+": if (sym1.m_values != null && sym2.m_values != null) result.m_values = MathUtilities.Add(sym1.m_values, sym2.m_values); else result.m_value = sym1.m_value + sym2.m_value; break; case "-": if (sym1.m_values != null && sym2.m_values != null) result.m_values = MathUtilities.Subtract(sym1.m_values, sym2.m_values); else result.m_value = sym1.m_value - sym2.m_value; break; default: result.m_type = ExpressionType.Error; result.m_name = "Undefine operator: " + opr.m_name + "."; break; } return result; }
/// <summary>Precedences the specified sym.</summary> /// <param name="sym">The sym.</param> /// <returns></returns> protected int Precedence(Symbol sym) { switch (sym.m_type) { case ExpressionType.Bracket: return 5; case ExpressionType.EvalFunction: return 4; case ExpressionType.Comma: return 0; } switch (sym.m_name) { case "^": return 3; case "/": case "*": case "%": return 2; case "+": case "-": return 1; } return -1; }
/// <summary>Evaluates the specified sym1.</summary> /// <param name="sym1">The sym1.</param> /// <param name="opr">The opr.</param> /// <param name="sym2">The sym2.</param> /// <returns></returns> protected Symbol Evaluate(Symbol sym1, Symbol opr, Symbol sym2) { Symbol result; result.m_name = sym1.m_name + opr.m_name + sym2.m_name; result.m_type = ExpressionType.Result; result.m_value = 0; result.m_values = null; switch (opr.m_name) { case "^": if (sym1.m_values != null) { result.m_values = new double[sym1.m_values.Length]; for (int i = 0; i < sym1.m_values.Length; i++) { result.m_values[i] = Math.Pow(sym1.m_values[i], sym2.m_value); } } else { result.m_value = System.Math.Pow(sym1.m_value, sym2.m_value); } break; case "/": { if (sym1.m_values != null && sym2.m_values != null) { result.m_values = MathUtilities.Divide(sym1.m_values, sym2.m_values); } else if (sym1.m_values != null) { result.m_values = MathUtilities.Divide_Value(sym1.m_values, sym2.m_value); } else if (sym2.m_values != null) { result.m_values = new double[sym2.m_values.Length]; for (int i = 0; i < result.m_values.Length; i++) { result.m_values[i] = MathUtilities.Divide(sym1.m_value, sym2.m_values[i], 0); } } else { if (sym2.m_value > 0) { result.m_value = sym1.m_value / sym2.m_value; } else { result.m_name = "Divide by Zero."; result.m_type = ExpressionType.Error; } } break; } case "*": if (sym1.m_values != null && sym2.m_values != null) { result.m_values = MathUtilities.Multiply(sym1.m_values, sym2.m_values); } else if (sym1.m_values != null) { result.m_values = MathUtilities.Multiply_Value(sym1.m_values, sym2.m_value); } else if (sym2.m_values != null) { result.m_values = MathUtilities.Multiply_Value(sym2.m_values, sym1.m_value); } else { result.m_value = sym1.m_value * sym2.m_value; } break; case "%": result.m_value = sym1.m_value % sym2.m_value; break; case "+": if (sym1.m_values != null && sym2.m_values != null) { result.m_values = MathUtilities.Add(sym1.m_values, sym2.m_values); } else if (sym1.m_values != null) { result.m_values = MathUtilities.AddValue(sym1.m_values, sym2.m_value); } else if (sym2.m_values != null) { result.m_values = MathUtilities.AddValue(sym2.m_values, sym1.m_value); } else { result.m_value = sym1.m_value + sym2.m_value; } break; case "-": if (sym1.m_values != null && sym2.m_values != null) { result.m_values = MathUtilities.Subtract(sym1.m_values, sym2.m_values); } else if (sym1.m_values != null) { result.m_values = MathUtilities.Subtract_Value(sym1.m_values, sym2.m_value); } else if (sym2.m_values != null) { result.m_values = new double[sym2.m_values.Length]; for (int i = 0; i < result.m_values.Length; i++) { result.m_values[i] = sym1.m_value - sym2.m_values[i]; } } else { result.m_value = sym1.m_value - sym2.m_value; } break; default: result.m_type = ExpressionType.Error; result.m_name = "Undefine operator: " + opr.m_name + "."; break; } return(result); }
/// <summary>Evaluates the postfix.</summary> public void EvaluatePostfix() { Symbol tpSym1, tpSym2, tpResult; Stack tpStack = new Stack(); ArrayList fnParam = new ArrayList(); m_bError = false; foreach (Symbol sym in m_postfix) { if ((sym.m_type == ExpressionType.Value) || (sym.m_type == ExpressionType.Variable) || (sym.m_type == ExpressionType.Result)) tpStack.Push(sym); else if (sym.m_type == ExpressionType.Operator) { tpSym1 = (Symbol)tpStack.Pop(); if (tpStack.Count > 0) tpSym2 = (Symbol)tpStack.Pop(); else tpSym2 = new Symbol(); tpResult = Evaluate(tpSym2, sym, tpSym1); if (tpResult.m_type == ExpressionType.Error) { m_bError = true; m_sErrorDescription = tpResult.m_name; return; } tpStack.Push(tpResult); } else if (sym.m_type == ExpressionType.EvalFunction) { fnParam.Clear(); tpSym1 = (Symbol)tpStack.Pop(); if ((tpSym1.m_type == ExpressionType.Value) || (tpSym1.m_type == ExpressionType.Variable) || (tpSym1.m_type == ExpressionType.Result)) { tpResult = EvaluateFunction(sym.m_name, tpSym1); if (tpResult.m_type == ExpressionType.Error) { m_bError = true; m_sErrorDescription = tpResult.m_name; return; } tpStack.Push(tpResult); } else if (tpSym1.m_type == ExpressionType.Comma) { while (tpSym1.m_type == ExpressionType.Comma) { tpSym1 = (Symbol)tpStack.Pop(); fnParam.Add(tpSym1); tpSym1 = (Symbol)tpStack.Pop(); } fnParam.Add(tpSym1); tpResult = EvaluateFunction(sym.m_name, fnParam.ToArray()); if (tpResult.m_type == ExpressionType.Error) { m_bError = true; m_sErrorDescription = tpResult.m_name; return; } tpStack.Push(tpResult); } else { tpStack.Push(tpSym1); tpResult = EvaluateFunction(sym.m_name); if (tpResult.m_type == ExpressionType.Error) { m_bError = true; m_sErrorDescription = tpResult.m_name; return; } tpStack.Push(tpResult); } } } if (tpStack.Count == 1) { tpResult = (Symbol)tpStack.Pop(); m_result = tpResult.m_value; if (tpResult.m_values != null) { m_results = tpResult.m_values; } } }
/// <summary>Evaluates the postfix.</summary> public void EvaluatePostfix() { Symbol tpSym1, tpSym2, tpResult; Stack tpStack = new Stack(); ArrayList fnParam = new ArrayList(); m_bError = false; foreach (Symbol sym in m_postfix) { if ((sym.m_type == ExpressionType.Value) || (sym.m_type == ExpressionType.Variable) || (sym.m_type == ExpressionType.Result)) { tpStack.Push(sym); } else if (sym.m_type == ExpressionType.Operator) { tpSym1 = (Symbol)tpStack.Pop(); if (tpStack.Count > 0) { tpSym2 = (Symbol)tpStack.Pop(); } else { tpSym2 = new Symbol(); } tpResult = Evaluate(tpSym2, sym, tpSym1); if (tpResult.m_type == ExpressionType.Error) { m_bError = true; m_sErrorDescription = tpResult.m_name; return; } tpStack.Push(tpResult); } else if (sym.m_type == ExpressionType.EvalFunction) { fnParam.Clear(); tpSym1 = (Symbol)tpStack.Pop(); if ((tpSym1.m_type == ExpressionType.Value) || (tpSym1.m_type == ExpressionType.Variable) || (tpSym1.m_type == ExpressionType.Result)) { tpResult = EvaluateFunction(sym.m_name, tpSym1); if (tpResult.m_type == ExpressionType.Error) { m_bError = true; m_sErrorDescription = tpResult.m_name; return; } tpStack.Push(tpResult); } else if (tpSym1.m_type == ExpressionType.Comma) { while (tpSym1.m_type == ExpressionType.Comma) { tpSym1 = (Symbol)tpStack.Pop(); fnParam.Add(tpSym1); tpSym1 = (Symbol)tpStack.Pop(); } fnParam.Add(tpSym1); tpResult = EvaluateFunction(sym.m_name, fnParam.ToArray()); if (tpResult.m_type == ExpressionType.Error) { m_bError = true; m_sErrorDescription = tpResult.m_name; return; } tpStack.Push(tpResult); } else { tpStack.Push(tpSym1); tpResult = EvaluateFunction(sym.m_name); if (tpResult.m_type == ExpressionType.Error) { m_bError = true; m_sErrorDescription = tpResult.m_name; return; } tpStack.Push(tpResult); } } } if (tpStack.Count == 1) { tpResult = (Symbol)tpStack.Pop(); m_result = tpResult.m_value; if (tpResult.m_values != null) { m_results = tpResult.m_values; } } }