コード例 #1
0
ファイル: ParserTests.cs プロジェクト: jsteripan/negroni
        private static void ValidateTokens(IList <TestToken> expectedTokens, IList <Element> tokens, string expression)
        {
            Assert.AreEqual(expectedTokens.Count, tokens.Count,
                            string.Format("Invalid number of tokens for expression {0}", expression));

            for (int j = 0; j < expectedTokens.Count; j++)
            {
                Assert.AreEqual(expectedTokens[j].Name, tokens[j].ToString(),
                                string.Format("Invalid number of tokens for expression {0}", expression));

                Assert.AreEqual(expectedTokens[j].TokenType, tokens[j].Type,
                                string.Format("Invalid type for expression {0}", expression));

                if (expectedTokens[j].TokenType == TokenType.Function)
                {
                    ElementFunction elementFunction = (ElementFunction)tokens[j];
                    Assert.AreEqual(expectedTokens[j].Parms.Count, elementFunction.Parameters.Count);
                    for (int k = 0; k < expectedTokens[j].Parms.Count; k++)
                    {
                        ValidateTokens(expectedTokens[j].Parms[k], elementFunction.Parameters[k], expression);
                    }
                }
            }
        }
コード例 #2
0
ファイル: Engine.cs プロジェクト: jsteripan/negroni
        private static IElementValue EvaluateExpression(IList <Element> data, IObjectResolver dc)
        {
            if (data.Count == 0)
            {
                return(null);
            }
            Stack <IElementValue> output = new Stack <IElementValue>();

            for (int j = 0; j < data.Count; j++)
            {
                Element element = data[j];
                switch (element.Type)
                {
                case TokenType.BinaryOperator:
                    ElementBinaryOperator binaryElement  = (ElementBinaryOperator)element;
                    BinaryOperator        binaryOperator = (BinaryOperator)binaryElement.Operator;
                    IElementValue         b2             = output.Pop();
                    IElementValue         b1             = output.Pop();
                    IElementValue         binaryOutput   = binaryOperator.Apply(b1, b2);
                    output.Push(binaryOutput);
                    break;

                case TokenType.UnitaryOperator:
                    ElementUnitaryOperator unitaryElement  = (ElementUnitaryOperator)element;
                    UnitaryOperator        unitaryOperator = (UnitaryOperator)unitaryElement.Operator;
                    IElementValue          u1            = output.Pop();
                    IElementValue          unitaryOutput = unitaryOperator.Apply(u1);
                    output.Push(unitaryOutput);
                    break;

                case TokenType.Function:
                    ElementFunction  functionElement  = (ElementFunction)element;
                    FunctionOperator functionOperator = (FunctionOperator)functionElement.Operator;
                    IElementValue[]  paramVals        = new IElementValue[functionElement.Parameters.Count];
                    for (int paramIndex = 0; paramIndex < functionElement.Parameters.Count; paramIndex++)
                    {
                        paramVals[paramIndex] = EvaluateExpression(functionElement.Parameters[paramIndex], dc);
                    }
                    IElementValue functionOutput = functionOperator.Apply(paramVals);
                    output.Push(functionOutput);
                    break;

                case TokenType.DecimalLiteral:
                case TokenType.IntegerLiteral:
                case TokenType.StringLiteral:
                case TokenType.BooleanLiteral:
                case TokenType.Selector:
                    output.Push((IElementValue)element);
                    break;

                case TokenType.OpenParenthesis:
                    int             parenthesis         = 1;
                    IList <Element> parenthesisElements = new List <Element>();
                    for (j = j + 1; j < data.Count; j++)
                    {
                        Element parenthesisElement = data[j];
                        if (parenthesisElement.Type == TokenType.OpenParenthesis)
                        {
                            parenthesis++;
                        }
                        else if (parenthesisElement.Type == TokenType.CloseParenthesis)
                        {
                            parenthesis--;
                            if (parenthesis == 0)
                            {
                                IElementValue parenthesisOutput = EvaluateExpression(parenthesisElements, dc);
                                output.Push(parenthesisOutput);
                                break;
                            }
                        }
                        else
                        {
                            parenthesisElements.Add(parenthesisElement);
                        }
                    }
                    break;

                case TokenType.TernaryIf:
                    IElementValue ternaryIfValue = output.Pop();
                    if (ternaryIfValue.Type != TokenType.BooleanLiteral)
                    {
                        throw new ELException("Condition is not boolean.");
                    }
                    bool            condition       = (bool)ternaryIfValue.Value;
                    IList <Element> ternaryElements = new List <Element>();
                    bool            elseReached     = false;
                    for (j = j + 1; j < data.Count; j++)
                    {
                        Element conditionValue = data[j];
                        if (conditionValue.Type == TokenType.TernaryElse)
                        {
                            elseReached = true;
                        }
                        if (condition == true)
                        {
                            if (elseReached == true)
                            {
                                j = data.Count;
                                break;
                            }
                            ternaryElements.Add(conditionValue);
                        }
                        else
                        {
                            if (elseReached == true)
                            {
                                ternaryElements.Add(conditionValue);
                            }
                        }
                    }
                    IElementValue ternaryOutput = EvaluateExpression(ternaryElements, dc);
                    output.Push(ternaryOutput);
                    break;

                case TokenType.Variable:
                    StringBuilder variableStr = new StringBuilder();
                    string        expression;
                    expression = ((ElementVariable)element).Expression;
                    variableStr.Append(expression);
                    bool variableBoundryHit = false;
                    bool end = false;
                    while (j + 1 < data.Count && end == false)
                    {
                        switch (data[j + 1].Type)
                        {
                        case TokenType.Variable:
                            if (!variableBoundryHit)
                            {
                                end = true;
                                break;
                            }
                            j++;
                            variableStr.Append(((ElementVariable)data[j]).Expression);
                            variableBoundryHit = false;
                            break;

                        case TokenType.OpenBracket:
                            j++;
                            int brackets = 1;
                            variableBoundryHit = true;
                            IList <Element> bracketElements = new List <Element>();
                            for (j = j + 1; j < data.Count; j++)
                            {
                                Element bracketElement = data[j];
                                if (bracketElement.Type == TokenType.OpenBracket)
                                {
                                    brackets++;
                                }
                                else if (bracketElement.Type == TokenType.CloseBracket)
                                {
                                    brackets--;
                                    if (brackets == 0)
                                    {
                                        IElementValue bracketOutput = EvaluateExpression(bracketElements, dc);
                                        if (bracketOutput.Type != TokenType.IntegerLiteral &&
                                            bracketOutput.Type != TokenType.Selector)
                                        {
                                            throw new ELException("Integers and Selectors can only be used as brackets indexes.");
                                        }
                                        variableStr.Append("[").Append(bracketOutput.Value).Append("]");
                                        break;
                                    }
                                }
                                else
                                {
                                    bracketElements.Add(bracketElement);
                                }
                            }
                            break;

                        case TokenType.Dot:
                            j++;
                            variableBoundryHit = true;
                            variableStr.Append(".");
                            break;

                        default:
                            end = true;
                            break;
                        }
                    }

                    object        value = dc.GetVariableObject(variableStr.ToString());
                    IElementValue elementValue;
                    if (value is string)
                    {
                        elementValue = new ElementLiteral(TokenType.StringLiteral, value);
                    }
                    else if (value is bool)
                    {
                        elementValue = new ElementLiteral(TokenType.BooleanLiteral, value);
                    }
                    else if (value is int)
                    {
                        elementValue = new ElementLiteral(TokenType.IntegerLiteral, value);
                    }
                    else if (value is double || value is float || value is decimal)
                    {
                        elementValue = new ElementLiteral(TokenType.DecimalLiteral, Convert.ToDouble(value));
                    }
                    else
                    {
                        elementValue = new ElementLiteral(TokenType.Object, value);
                    }
                    output.Push(elementValue);
                    break;
                }
            }
            if (output.Count != 1)
            {
                throw new ELException("Error evaluating expression");
            }
            return((IElementValue)output.Pop());
        }