private static string GetPostfixNotationFromFunctionNotation(string Expression) {
int i = Expression.IndexOf('[');
if (i >= 0) {
if (!Expression.EndsWith("]")) {
throw new System.IO.InvalidDataException("Missing closing bracket encountered in " + Expression);
}
} else {
if (Expression.EndsWith("]")) {
throw new System.IO.InvalidDataException("Unexpected closing bracket encountered in " + Expression);
} else {
double value;
if (double.TryParse(Expression, System.Globalization.NumberStyles.Float, System.Globalization.CultureInfo.InvariantCulture, out value)) {
return Expression;
} else {
for (int j = 0; j < Expression.Length; j++) {
if (!char.IsLetterOrDigit(Expression[j])) {
throw new System.IO.InvalidDataException("Invalid character encountered in variable " + Expression);
}
}
return Expression;
}
}
}
string f = Expression.Substring(0, i);
string s = Expression.Substring(i + 1, Expression.Length - i - 2);
string[] a = new string[4];
int n = 0;
int b = 0;
for (i = 0; i < s.Length; i++) {
switch (s[i]) {
case '[':
{
i++; int m = 1;
bool q = false;
while (i < s.Length) {
switch (s[i]) {
case '[':
m++;
break;
case ']':
m--;
if (m < 0) {
throw new System.IO.InvalidDataException("Unexpected closing bracket encountered in " + Expression);
} else if (m == 0) {
q = true;
}
break;
}
if (q) {
break;
}
i++;
} if (!q) {
throw new System.IO.InvalidDataException("No closing bracket found in " + Expression);
}
} break;
case ']':
throw new System.IO.InvalidDataException("Unexpected closing bracket encountered in " + Expression);
case ',':
if (n == a.Length) {
Array.Resize<string>(ref a, n << 1);
}
a[n] = s.Substring(b, i - b).Trim();
n++;
b = i + 1;
break;
}
}
if (n == a.Length) {
Array.Resize<string>(ref a, n << 1);
}
a[n] = s.Substring(b).Trim();
n++;
if (n == 1 & a[0].Length == 0) {
n = 0;
}
for (i = 0; i < n; i++) {
if (a[i].Length == 0) {
throw new System.IO.InvalidDataException("An empty argument is invalid in " + f + " in " + Expression);
} else if (a[i].IndexOf(' ') >= 0) {
throw new System.IO.InvalidDataException("An argument containing a space is invalid in " + f + " in " + Expression);
}
a[i] = GetPostfixNotationFromFunctionNotation(a[i]).Trim();
}
switch (f.ToLowerInvariant()) {
// arithmetic
case "plus":
if (n == 0) {
return "0";
} else if (n == 1) {
return a[0];
} else if (n == 2) {
if (a[1].EndsWith(" *")) {
return a[1] + " " + a[0] + " +";
} else {
return a[0] + " " + a[1] + " +";
}
} else {
System.Text.StringBuilder t = new System.Text.StringBuilder(a[0] + " " + a[1] + " +");
for (i = 2; i < n; i++) {
t.Append(" " + a[i] + " +");
}
return t.ToString();
}
case "subtract":
if (n == 2) {
return a[0] + " " + a[1] + " -";
} else {
throw new System.IO.InvalidDataException(f + " is expected to have 2 arguments in " + Expression);
}
case "times":
if (n == 0) {
return "1";
} else if (n == 1) {
return a[0];
} else if (n == 2) {
return a[0] + " " + a[1] + " *";
} else {
System.Text.StringBuilder t = new System.Text.StringBuilder(a[0] + " " + a[1] + " *");
for (i = 2; i < n; i++) {
t.Append(" " + a[i] + " *");
}
return t.ToString();
}
case "divide":
if (n == 2) {
return a[0] + " " + a[1] + " /";
} else {
throw new System.IO.InvalidDataException(f + " is expected to have 2 arguments in " + Expression);
}
case "power":
if (n == 0) {
return "1";
} else if (n == 1) {
return a[0];
} else if (n == 2) {
return a[0] + " " + a[1] + " power";
} else {
System.Text.StringBuilder t = new System.Text.StringBuilder(a[0] + " " + a[1]);
for (i = 2; i < n; i++) {
t.Append(" " + a[i]);
}
for (i = 0; i < n - 1; i++) {
t.Append(" power");
}
return t.ToString();
}
// math
case "quotient":
case "mod":
case "min":
case "max":
case "random":
case "randomint":
if (n == 2) {
return a[0] + " " + a[1] + " " + f;
} else {
throw new System.IO.InvalidDataException(f + " is expected to have 2 arguments in " + Expression);
}
case "minus":
case "reciprocal":
case "floor":
case "ceiling":
case "round":
case "abs":
case "sign":
case "exp":
case "log":
case "sqrt":
case "sin":
case "cos":
case "tan":
case "arctan":
if (n == 1) {
return a[0] + " " + f;
} else {
throw new System.IO.InvalidDataException(f + " is expected to have 1 argument in " + Expression);
}
// comparisons
case "equal":
case "unequal":
case "less":
case "greater":
case "lessequal":
case "greaterequal":
if (n == 2) {
string g; switch (f.ToLowerInvariant()) {
case "equal": g = "=="; break;
case "unequal": g = "!="; break;
case "less": g = "<"; break;
case "greater": g = ">"; break;
case "lessequal": g = "<="; break;
case "greaterequal": g = ">="; break;
default: g = "halt"; break;
}
return a[0] + " " + a[1] + " " + g;
} else {
throw new System.IO.InvalidDataException(f + " is expected to have 2 arguments in " + Expression);
}
case "if":
if (n == 3) {
return a[0] + " " + a[1] + " " + a[2] + " ?";
} else {
throw new System.IO.InvalidDataException(f + " is expected to have 3 arguments in " + Expression);
}
// logical
case "not":
if (n == 1) {
return a[0] + " !";
} else {
throw new System.IO.InvalidDataException(f + " is expected to have 1 argument in " + Expression);
}
case "and":
if (n == 0) {
return "1";
} else if (n == 1) {
return a[0];
} else if (n == 2) {
return a[0] + " " + a[1] + " &";
} else {
System.Text.StringBuilder t = new System.Text.StringBuilder(a[0] + " " + a[1] + " +");
for (i = 2; i < n; i++) {
t.Append(" " + a[i] + " &");
} return t.ToString();
}
case "or":
if (n == 0) {
return "0";
} else if (n == 1) {
return a[0];
} else if (n == 2) {
return a[0] + " " + a[1] + " |";
} else {
System.Text.StringBuilder t = new System.Text.StringBuilder(a[0] + " " + a[1] + " +");
for (i = 2; i < n; i++) {
t.Append(" " + a[i] + " |");
} return t.ToString();
}
case "xor":
if (n == 0) {
return "0";
} else if (n == 1) {
return a[0];
} else if (n == 2) {
return a[0] + " " + a[1] + " ^";
} else {
System.Text.StringBuilder t = new System.Text.StringBuilder(a[0] + " " + a[1] + " +");
for (i = 2; i < n; i++) {
t.Append(" " + a[i] + " ^");
} return t.ToString();
}
// train
case "distance":
case "trackdistance":
case "curveradius":
case "frontaxlecurveradius":
case "rearaxlecurveradius":
case "curvecant":
case "odometer":
case "speed":
case "speedometer":
case "acceleration":
case "accelerationmotor":
case "doors":
case "leftdoors":
case "rightdoorstarget":
case "leftdoorstarget":
case "rightdoors":
case "mainreservoir":
case "equalizingreservoir":
case "brakepipe":
case "brakecylinder":
case "straightairpipe":
if (n == 1) {
return a[0] + " " + f.ToLowerInvariant() + "index";
} else {
throw new System.IO.InvalidDataException(f + " is expected to have 1 argument in " + Expression);
}
case "pluginstate":
if (n == 1) {
return a[0] + " pluginstate";
} else {
throw new System.IO.InvalidDataException(f + " is expected to have 1 argument in " + Expression);
}
// not supported
default:
throw new System.IO.InvalidDataException("The function " + f + " is not supported in " + Expression);
}
}