Пример #1
0
        private static ExpressionBase ParseComparison(PositionalTokenizer tokenizer, ExpressionBase left, ComparisonOperation operation, int joinerLine, int joinerColumn)
        {
            var right = ParseExpression(tokenizer, OperationPriority.Compare);

            switch (right.Type)
            {
            case ExpressionType.ParseError:
                return(right);

            case ExpressionType.BooleanConstant:
            case ExpressionType.Conditional:     // will be rebalanced
            case ExpressionType.FloatConstant:
            case ExpressionType.FunctionCall:
            case ExpressionType.IntegerConstant:
            case ExpressionType.Mathematic:
            case ExpressionType.StringConstant:
            case ExpressionType.Variable:
                break;

            default:
                var expressionTokenizer = tokenizer as ExpressionTokenizer;
                if (expressionTokenizer != null)
                {
                    expressionTokenizer.QueueExpression(right);
                }

                right = new KeywordExpression(ComparisonExpression.GetOperatorString(operation), joinerLine, joinerColumn);
                return(ParseError(tokenizer, "Incompatible comparison", right));
            }

            return(new ComparisonExpression(left, operation, right));
        }
Пример #2
0
        /// <summary>
        /// Replaces the variables in the expression with values from <paramref name="scope" />.
        /// </summary>
        /// <param name="scope">The scope object containing variable values.</param>
        /// <param name="result">[out] The new expression containing the replaced variables.</param>
        /// <returns>
        ///   <c>true</c> if substitution was successful, <c>false</c> if something went wrong, in which case <paramref name="result" /> will likely be a <see cref="ParseErrorExpression" />.
        /// </returns>
        public override bool ReplaceVariables(InterpreterScope scope, out ExpressionBase result)
        {
            ExpressionBase left;

            if (!Left.ReplaceVariables(scope, out left))
            {
                result = left;
                return(false);
            }

            ExpressionBase right;

            if (!Right.ReplaceVariables(scope, out right))
            {
                result = right;
                return(false);
            }

            var comparison = new ComparisonExpression(left, Operation, right);

            CopyLocation(comparison);
            result = comparison;
            return(true);
        }
Пример #3
0
        internal static ExpressionBase InvertExpression(ExpressionBase expression)
        {
            // logical inversion
            var condition = expression as ConditionalExpression;

            if (condition != null)
            {
                var newConditions = new List <ExpressionBase>(condition._conditions.Count);
                foreach (var oldCondition in condition._conditions)
                {
                    newConditions.Add(InvertExpression(oldCondition));
                }

                switch (condition.Operation)
                {
                case ConditionalOperation.Not:
                    // !(!A) => A
                    return(newConditions[0]);

                case ConditionalOperation.And:
                    // !(A && B) => !A || !B
                    return(new ConditionalExpression(ConditionalOperation.Or, newConditions));

                case ConditionalOperation.Or:
                    // !(A || B) => !A && !B
                    return(new ConditionalExpression(ConditionalOperation.And, newConditions));

                default:
                    throw new NotImplementedException("Unsupported condition operation");
                }
            }

            // comparative inversion
            var comparison = expression as ComparisonExpression;

            if (comparison != null)
            {
                // !(A == B) => A != B, !(A < B) => A >= B, ...
                return(new ComparisonExpression(
                           comparison.Left,
                           ComparisonExpression.GetOppositeComparisonOperation(comparison.Operation),
                           comparison.Right));
            }

            // boolean constant
            var boolean = expression as BooleanConstantExpression;

            if (boolean != null)
            {
                return(new BooleanConstantExpression(!boolean.Value));
            }

            // special handling for built-in functions
            var function = expression as FunctionCallExpression;

            if (function != null && function.Parameters.Count() == 0)
            {
                if (function.FunctionName.Name == "always_true")
                {
                    return(AlwaysFalseFunction.CreateAlwaysFalseFunctionCall());
                }

                if (function.FunctionName.Name == "always_false")
                {
                    return(AlwaysTrueFunction.CreateAlwaysTrueFunctionCall());
                }
            }

            // unsupported inversion
            return(new ParseErrorExpression("! operator cannot be applied to " + expression.Type, expression));
        }
Пример #4
0
        private static ExpressionBase ParseComparison(PositionalTokenizer tokenizer, ExpressionBase left, ComparisonOperation operation, int joinerLine, int joinerColumn)
        {
            var right = ExpressionBase.Parse(tokenizer);

            switch (right.Type)
            {
            case ExpressionType.ParseError:
                return(right);

            case ExpressionType.Conditional:     // will be rebalanced
            case ExpressionType.FunctionCall:
            case ExpressionType.IntegerConstant:
            case ExpressionType.Mathematic:
            case ExpressionType.StringConstant:
            case ExpressionType.Variable:
                break;

            default:
                ParseError(tokenizer, "incompatible comparison", new KeywordExpression(ComparisonExpression.GetOperatorString(operation), joinerLine, joinerColumn));
                break;
            }

            return(new ComparisonExpression(left, operation, right));
        }