in Configurator/Core/Ini/FormulaEngine.cs [63:297]
public string Evaluate()
{
var result = new Stack();
var resultToken = new FormulaToken();
// While there are input tokens left
foreach (object obj in _output)
{
// Read the next token from input.
var token = (FormulaToken)obj;
FormulaToken operand1;
FormulaToken operand2;
switch (token.TokenValueType)
{
case FormulaTokenType.Number:
case FormulaTokenType.Constant:
case FormulaTokenType.Variable:
result.Push(token);
break;
case FormulaTokenType.Assignment:
if (result.Count >= 2)
{
operand2 = (FormulaToken)result.Pop();
operand1 = (FormulaToken)result.Pop();
if (operand1.TokenValueType == FormulaTokenType.Variable
&& (operand2.TokenValueType == FormulaTokenType.Number
|| operand2.TokenValueType == FormulaTokenType.Constant
|| operand2.TokenValueType == FormulaTokenType.Variable))
{
_formulaVariables[operand1.TokenValue] = GetTokenValue(operand2).ToString(CultureInfo.CurrentCulture);
}
else
{
throw new Exception("Assignment error!");
}
result.Push(operand1);
}
else
{
throw new Exception("Evaluation error!");
}
break;
case FormulaTokenType.Plus:
if (result.Count >= 2)
{
operand2 = (FormulaToken)result.Pop();
operand1 = (FormulaToken)result.Pop();
resultToken.TokenValueType = FormulaTokenType.Number;
resultToken.TokenValue = (GetTokenValue(operand2) + GetTokenValue(operand1)).ToString(CultureInfo.CurrentCulture);
result.Push(resultToken);
}
else
{
throw new Exception("Evaluation error!");
}
break;
case FormulaTokenType.Minus:
if (result.Count >= 2)
{
operand2 = (FormulaToken)result.Pop();
operand1 = (FormulaToken)result.Pop();
resultToken.TokenValueType = FormulaTokenType.Number;
resultToken.TokenValue = (GetTokenValue(operand1) - GetTokenValue(operand2)).ToString(CultureInfo.CurrentCulture);
result.Push(resultToken);
}
else
{
throw new Exception("Evaluation error!");
}
break;
case FormulaTokenType.Multiply:
if (result.Count >= 2)
{
operand2 = (FormulaToken)result.Pop();
operand1 = (FormulaToken)result.Pop();
resultToken.TokenValueType = FormulaTokenType.Number;
resultToken.TokenValue = (GetTokenValue(operand2) * GetTokenValue(operand1)).ToString(CultureInfo.CurrentCulture);
result.Push(resultToken);
}
else
{
throw new Exception("Evaluation error!");
}
break;
case FormulaTokenType.Divide:
if (result.Count >= 2)
{
operand2 = (FormulaToken)result.Pop();
operand1 = (FormulaToken)result.Pop();
resultToken.TokenValueType = FormulaTokenType.Number;
resultToken.TokenValue = (GetTokenValue(operand1) / GetTokenValue(operand2)).ToString(CultureInfo.CurrentCulture);
result.Push(resultToken);
}
else
{
throw new Exception("Evaluation error!");
}
break;
case FormulaTokenType.Exponent:
if (result.Count >= 2)
{
operand2 = (FormulaToken)result.Pop();
operand1 = (FormulaToken)result.Pop();
resultToken.TokenValueType = FormulaTokenType.Number;
resultToken.TokenValue = Math.Pow(GetTokenValue(operand1), GetTokenValue(operand2)).ToString(CultureInfo.CurrentCulture);
result.Push(resultToken);
}
else
{
throw new Exception("Evaluation error!");
}
break;
case FormulaTokenType.UnaryMinus:
if (result.Count >= 1)
{
operand1 = (FormulaToken)result.Pop();
resultToken.TokenValueType = FormulaTokenType.Number;
resultToken.TokenValue = (-GetTokenValue(operand1)).ToString(CultureInfo.CurrentCulture);
result.Push(resultToken);
}
else
{
throw new Exception("Evaluation error!");
}
break;
case FormulaTokenType.Sine:
if (result.Count >= 1)
{
operand1 = (FormulaToken)result.Pop();
resultToken.TokenValueType = FormulaTokenType.Number;
resultToken.TokenValue = Math.Sin(GetTokenValue(operand1)).ToString(CultureInfo.CurrentCulture);
result.Push(resultToken);
}
else
{
throw new Exception("Evaluation error!");
}
break;
case FormulaTokenType.Cosine:
if (result.Count >= 1)
{
operand1 = (FormulaToken)result.Pop();
resultToken.TokenValueType = FormulaTokenType.Number;
resultToken.TokenValue = Math.Cos(GetTokenValue(operand1)).ToString(CultureInfo.CurrentCulture);
result.Push(resultToken);
}
else
{
throw new Exception("Evaluation error!");
}
break;
case FormulaTokenType.Tangent:
if (result.Count >= 1)
{
operand1 = (FormulaToken)result.Pop();
resultToken.TokenValueType = FormulaTokenType.Number;
resultToken.TokenValue = Math.Tan(GetTokenValue(operand1)).ToString(CultureInfo.CurrentCulture);
result.Push(resultToken);
}
else
{
throw new Exception("Evaluation error!");
}
break;
case FormulaTokenType.Round:
if (result.Count >= 2)
{
operand2 = (FormulaToken)result.Pop();
operand1 = (FormulaToken)result.Pop();
resultToken.TokenValueType = FormulaTokenType.Number;
resultToken.TokenValue = Math.Round((GetTokenValue(operand1) / GetTokenValue(operand2)) * GetTokenValue(operand2)).ToString(CultureInfo.CurrentCulture);
result.Push(resultToken);
}
else
{
throw new Exception("Evaluation error!");
}
break;
case FormulaTokenType.Max:
if (result.Count >= 2)
{
operand2 = (FormulaToken)result.Pop();
operand1 = (FormulaToken)result.Pop();
result.Push(GetTokenValue(operand1) >= GetTokenValue(operand2) ? operand1 : operand2);
}
else
{
throw new Exception("Evaluation error!");
}
break;
case FormulaTokenType.Min:
if (result.Count >= 2)
{
operand2 = (FormulaToken)result.Pop();
operand1 = (FormulaToken)result.Pop();
result.Push(GetTokenValue(operand1) <= GetTokenValue(operand2) ? operand1 : operand2);
}
else
{
throw new Exception("Evaluation error!");
}
break;
}
}
switch (result.Count)
{
case 0:
// No value on the stack means there is no value associated with a parameter.
return "";
case 1:
// If there is only one value in the stack, that value is the result of the calculation.
return GetTokenText((FormulaToken)result.Pop());
default:
// If there are more values in the stack
// (Error) The user input too many values.
throw new Exception("Evaluation error. Invalid number of arguments.");
}
}