static double ParseSymbols(SymbolList syms)
{
bool transformNextValue = false;
double sum = 0;
double curTerm = 0;
SymbolType prevOper = SymbolType.OperatorAdd;
int len = syms.symbols.Count;
var symbolList = syms.symbols;
for (int i=0;i<len;i++)
{
var s = symbolList[i];
switch (s.type)
{
case SymbolType.RealValue:
case SymbolType.SubExpression:
case SymbolType.StringLiteral:
case SymbolType.StringVariable:
{
double value;
if (transformNextValue)
{
var funcSymbol = symbolList[i-1];
switch (funcSymbol.type)
{
case SymbolType.Pow:
{
value = System.Math.Pow(GetSymbolValue(s),GetSymbolValue(symbolList[i+1]));
i++;
break;
}
case SymbolType.FuncCustom:
{
var customFunc = (CustomFunction)funcSymbol.ptr;
if (customFunc.paramCount == 1 && customFunc.func1d != null)
{
value = customFunc.Invoke(GetSymbolValue(s));
}
else if (customFunc.funcmo != null)
{
object[] p = new object[MaxCustomFunctionParamCount];
p[0] = (!s.IsStringType()) ? (object)GetSymbolValue(s) : (object)s.stringValue;
for (int g=1;g<customFunc.paramCount;g++)
{
p[g] = (!symbolList[i+1].IsStringType()) ? (object)GetSymbolValue(symbolList[i+1]) : (object)symbolList[i+1].stringValue;
i++;
}
value = customFunc.Invoke(p);
}
else
{
double[] p = new double[MaxCustomFunctionParamCount];
p[0] = GetSymbolValue(s);
for (int g=1;g<customFunc.paramCount;g++)
{
p[g] = GetSymbolValue(symbolList[i+1]);
i++;
}
value = customFunc.Invoke(p);
}
break;
}
default:
throw new System.Exception("Very unexpected parse error.");
}
transformNextValue = false;
}
else
{
// The value cant be a string because they appear only as parameters to functions
value = GetSymbolValue(s);
}
switch (prevOper)
{
case SymbolType.OperatorMultiply:
curTerm *= value;
break;
case SymbolType.OperatorDivide:
curTerm /= value;
break;
case SymbolType.OperatorAdd:
sum += curTerm;
curTerm = value;
break;
default:
throw new System.Exception("Very unexpected parse error.");
}
prevOper = SymbolType.OperatorMultiply;
break;
}
case SymbolType.OperatorDivide:
case SymbolType.OperatorAdd:
prevOper = s.type;
break;
case SymbolType.Pow:
case SymbolType.FuncCustom:
transformNextValue = true;
break;
default:
throw new System.Exception("Unable to parse symbols.");
}
}
// Remember to add the final term to sum
return sum + curTerm;
}