/// <summary> /// The primary function that make the expression that will be compiled then evaluated. /// </summary> /// <param name="tokens"></param> /// <returns></returns> public Expression FormTheExpression(Token tokens) { Expression quantityExpression = null; ExprOp eop = null; ExprOp FirstEop = null; int ix = 0; //this is the index in the discovered tokens while (ix < tokens.Count) { string q = tokens[ix].TokenValue; string op = ix + 1 < tokens.Count ? tokens[ix + 1].TokenValue : string.Empty; if (q == "+" || q == "-") { // unary prefix operator. //consume another token for number if (q == "+") { //q = tokens[ix].TokenValue; quantityExpression = Expression.Constant(1.0); } else { quantityExpression = Expression.Constant(-1.0); } op = "_h*"; ix--; goto ExpressionCompleted; } if (tokens[ix].TokenClassType == typeof(IfWordToken)) { // this is an If Word so we need to take all the tokens after it until we find THEN token // and form expression. int ifClosingIndex; Token IfBodyToken = tokens.SubTokens(ix + 1, typeof(ThenWordToken), out ifClosingIndex); int thenClosingIndex; Token ThenBodyToken = null; int elseClosingIndex; Token ElseBodyToken = null; ix = ifClosingIndex; if (ix < tokens.Count) { if (tokens[ifClosingIndex].TokenClassType == typeof(ThenWordToken)) { // True part evaluation ThenBodyToken = tokens.SubTokens(ix + 1, typeof(ElseWordToken), out thenClosingIndex); ix = thenClosingIndex; if (ix < tokens.Count) { if (tokens[thenClosingIndex].TokenClassType == typeof(ElseWordToken)) { // True part evaluation ElseBodyToken = tokens.SubTokens(ix + 1, typeof(ElseWordToken), out elseClosingIndex); ix = elseClosingIndex; } } } } Expression TestPart = FormTheExpression(IfBodyToken); Expression TruePart; Expression FalsePart; if (ThenBodyToken != null) TruePart = Expression.Convert(FormTheExpression(ThenBodyToken), typeof(object)); else TruePart = Expression.Constant(true, typeof(object)); if (ElseBodyToken != null) FalsePart = Expression.Convert(FormTheExpression(ElseBodyToken), typeof(object)); else FalsePart = Expression.Constant(false, typeof(object)); quantityExpression = Expression.Condition(TestPart, TruePart, FalsePart); } else if (tokens[ix].TokenClassType == typeof(ParenthesisCallToken)) { quantityExpression = FunctionCallExpression(tokens[ix]); } else if (tokens[ix].TokenClassType == typeof(ParenthesisGroupToken)) { // take the inner tokens and send it to be parsed again. quantityExpression = FormTheExpression(tokens[ix].RemoveSpaceTokens().TrimTokens(1, 1)); } else if (tokens[ix].TokenClassType == typeof(SymbolicToken)) { // quantityExpression = ExternalFieldHandleExpression(tokens[ix]); } else if (tokens[ix].TokenClassType == typeof(NumberToken)) { // quantityExpression = Expression.Constant(double.Parse(tokens[ix].TokenValue)); } else if (tokens[ix].TokenClassType == typeof(WordToken)) { // we are taking about internal variable storage quantityExpression = InternalFieldHandleExpression(tokens[ix]); } else if (tokens[ix].TokenClassType == typeof(TextToken)) { quantityExpression = Expression.Constant(tokens[ix].TrimTokens(1, 1).TokenValue); } else { throw new UnRecognizedException("Token: " + tokens[ix].TokenValue + " was not identified"); } ExpressionCompleted: if (eop == null) { //firs time creation FirstEop = new ExprOp(); eop = FirstEop; } else { //use the next object to be eop. eop.Next = new ExprOp(); eop = eop.Next; } eop.Operation = op; eop.ValueExpression = quantityExpression; ix += 2; } //then form the calculation expression return ConstructExpression(FirstEop); }