PHP Code:
#define MAX_COMPLEXITY 2147483647
enum Operators
{
Operator_None = 0,
Operator_Add,
Operator_Subtract,
Operator_Multiply,
Operator_Divide,
Operator_Exponental,
};
stock void Operate(ArrayList sumArray, ArrayList operatorArray, int bracket, float value)
{
float sum = sumArray.Get(bracket);
switch (operatorArray.Get(bracket))
{
case Operator_Add:
sum += value;
case Operator_Subtract:
sum -= value;
case Operator_Multiply:
sum *= value;
case Operator_Divide:
{
if (FloatCompare(value, -0.0000001) == 1 && FloatCompare(value, 0.0000001) == -1)
return;
sum /= value;
}
case Operator_Exponental:
sum = Pow(sum, value);
default:
sum = value;
}
sumArray.Set(bracket, sum);
operatorArray.Set(bracket, Operator_None);
}
stock void OperateString(ArrayList sumArray, ArrayList operatorArray, int bracket, char[] value, int size)
{
if (StrEqual(value, ""))
return;
Operate(sumArray, operatorArray, bracket, StringToFloat(value));
strcopy(value, size, "");
}
stock float eval(const char[] formula)
{
int bracket = 0, size = strlen(formula);
char buffer[2], strValue[1024];
ArrayList sumArray = new ArrayList(.startsize=1), operatorArray = new ArrayList(.startsize=1);
for (int i = 0; i <= size; i++)
{
buffer[0] = formula[i];
switch (buffer[0])
{
case ' ': //Ignore whitespace.
continue;
case '\0':
{
OperateString(sumArray, operatorArray, bracket, strValue, sizeof(strValue));
break; //As far as I know of, this doesn't break the switch statement and instead targets the for loop.
}
case '(':
{
if (bracket == MAX_COMPLEXITY)
{
LogError("Formula %s is too complex for this stock.", formula);
return 0.0;
}
bracket++;
if (bracket + 1 > sumArray.Length)
{
sumArray.Push(0.0);
operatorArray.Push(Operator_None);
}
else
{
sumArray.Set(bracket, 0.0);
operatorArray.Set(bracket, Operator_None);
}
}
case ')':
{
if (bracket == 0)
{
LogError("Formula %s has too many ')'.", formula);
return 0.0;
}
OperateString(sumArray, operatorArray, bracket, strValue, sizeof(strValue));
bracket--;
Operate(sumArray, operatorArray, bracket, sumArray.Get(bracket+1));
}
case '+', '-', '*', '/', '^':
{
OperateString(sumArray, operatorArray, bracket, strValue, sizeof(strValue));
switch (buffer[0])
{
case '+':
operatorArray.Set(bracket, Operator_Add);
case '-':
operatorArray.Set(bracket, Operator_Subtract);
case '*':
operatorArray.Set(bracket, Operator_Multiply);
case '/':
operatorArray.Set(bracket, Operator_Divide);
case '^':
operatorArray.Set(bracket, Operator_Exponental);
}
}
case '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', '.':
StrCat(strValue, sizeof(strValue), buffer);
//Insert case statements for any custom variables here.
default:
{
LogError("Formula %s contains invalid character %c", formula, buffer[0]);
return 0.0;
}
}
}
if (bracket > 0)
{
LogError("Formula %s is invalid, missing some ')'", formula);
return 0.0;
}
float ret = sumArray.Get(0);
delete sumArray;
delete operatorArray;
return ret;
}