Beispiel #1
0
        public override object Eval(TemplateContext context)
        {
            // evaluate both parts
            object lv = LeftExpression.Eval(context);
            object rv = RightExpression.Eval(context);

            // equality/not-equality
            if (op == TokenType.Equal)
            {
                if (lv == null && rv == null)
                {
                    return(true);
                }
                else if (lv != null)
                {
                    return(lv.Equals(rv));
                }
            }
            else if (op == TokenType.NotEqual)
            {
                if (lv == null && rv == null)
                {
                    return(false);
                }
                else if (lv != null)
                {
                    return(!lv.Equals(rv));
                }
            }

            // arithmetic operation
            else if (op == TokenType.Mult ||
                     op == TokenType.Div ||
                     op == TokenType.Mod ||
                     op == TokenType.Plus ||
                     op == TokenType.Minus ||
                     op == TokenType.Less ||
                     op == TokenType.LessOrEqual ||
                     op == TokenType.Greater ||
                     op == TokenType.GreaterOrEqual)
            {
                if (!((lv is Decimal || lv is Int32) && (rv is Decimal || rv is Int32)))
                {
                    throw new ParserException("Arithmetic and logical operations can be applied to operands or integer and decimal types only.",
                                              Line, Column);
                }


                bool   dec = lv is Decimal || rv is Decimal;
                object val = null;
                if (op == TokenType.Mult)
                {
                    val = dec ? (Decimal)lv * (Decimal)rv : (Int32)lv * (Int32)rv;
                }
                else if (op == TokenType.Div)
                {
                    val = dec ? (Decimal)lv / (Decimal)rv : (Int32)lv / (Int32)rv;
                }
                else if (op == TokenType.Mod)
                {
                    val = dec ? (Decimal)lv % (Decimal)rv : (Int32)lv % (Int32)rv;
                }
                else if (op == TokenType.Plus)
                {
                    val = dec ? (Decimal)lv + (Decimal)rv : (Int32)lv + (Int32)rv;
                }
                else if (op == TokenType.Minus)
                {
                    val = dec ? (Decimal)lv - (Decimal)rv : (Int32)lv - (Int32)rv;
                }
                else if (op == TokenType.Less)
                {
                    val = dec ? (Decimal)lv < (Decimal)rv : (Int32)lv < (Int32)rv;
                }
                else if (op == TokenType.LessOrEqual)
                {
                    val = dec ? (Decimal)lv <= (Decimal)rv : (Int32)lv <= (Int32)rv;
                }
                else if (op == TokenType.Greater)
                {
                    val = dec ? (Decimal)lv > (Decimal)rv : (Int32)lv > (Int32)rv;
                }
                else if (op == TokenType.GreaterOrEqual)
                {
                    val = dec ? (Decimal)lv >= (Decimal)rv : (Int32)lv >= (Int32)rv;
                }

                if (val is Boolean)
                {
                    bool ret = Convert.ToBoolean(val);
                    return(ret);
                }
                else if (dec)
                {
                    decimal ret = Convert.ToDecimal(val);
                    return(ret);
                }
                else
                {
                    int ret = Convert.ToInt32(val);
                    return(ret);
                }
            }
            else if (op == TokenType.Or || op == TokenType.And)
            {
                if (!(lv is Boolean && rv is Boolean))
                {
                    throw new ParserException("Logical operation can be applied to operands of boolean type only", Line, Column);
                }

                if (op == TokenType.Or)
                {
                    return((Boolean)lv || (Boolean)rv);
                }
                else if (op == TokenType.And)
                {
                    return((Boolean)lv && (Boolean)rv);
                }
            }

            return(0);
        }
 decimal IExpression.Interpret()
 {
     return(LeftExpression.Interpret() + RightExpression.Interpret());
 }
 public Expression Generate(Parameter parameter, LeftExpression left, RightExpression right, FilterAttribute filterAttribute, object value)
 {
     return(Expression.Call(left.GetExpression(), typeof(string).GetMethod(CONTAINS_METHOD_NAME, new[] { typeof(string) }), right.GetExpression()));
 }
Beispiel #4
0
        public override string Template()
        {
            return($"{RightExpression.Template()}\nmovq\t%rax,%rbx\n{LeftExpression.Template()}\n{AssignmentTemplate}\n{LeftExpression.Save()}");

            // var retrieve = $"\nmovq\t{varIndex}(%rbp),%rax";
            // const string div = "\nidiv\t%rbx";
            // var assign = $"\nmovq\t%rax,{varIndex}(%rbp)";
            //
            // return $"{Expression.Template()}" +
            //        "\nmovq\t%rax,%rbx" +
            //        retrieve +
            //        "\ncqo" +
            //        div +
            //        assign;
        }
Beispiel #5
0
 public override int Evaluate()
 {
     return(LeftExpression.Evaluate() - RightExpression.Evaluate());
 }
Beispiel #6
0
        /// <inheritdoc />
        protected override EvaluationResult DoEval(Context context, ModuleLiteral env, EvaluationStackFrame frame)
        {
            var leftCandidate = LeftExpression.Eval(context, env, frame);

            if (leftCandidate.IsErrorValue)
            {
                return(EvaluationResult.Error);
            }

            EvaluationResult left  = leftCandidate;
            EvaluationResult right = default(EvaluationResult);

            if (OperatorKind != BinaryOperator.And && OperatorKind != BinaryOperator.Or)
            {
                // Don't eval right expression for And and Or operators due to possible short circuit.
                var rightCandidate = RightExpression.Eval(context, env, frame);

                if (rightCandidate.IsErrorValue)
                {
                    return(EvaluationResult.Error);
                }

                right = rightCandidate;
            }

            try
            {
                checked
                {
                    int leftNumber;
                    int rightNumber;

                    switch (OperatorKind)
                    {
                    case BinaryOperator.Addition:
                        // Different cases:

                        // 1. If left OR right is a string result is a string
                        // 2. If left AND right are numbers - result is a number
                        string leftString  = left.Value as string;
                        string rightString = right.Value as string;

                        // First case: if any of the frame is string
                        if (leftString != null)
                        {
                            if (rightString != null)
                            {
                                return(EvaluationResult.Create(leftString + rightString));
                            }

                            return(EvaluationResult.Create(leftString + ToStringConverter.ObjectToString(context, right)));
                        }

                        if (rightString != null)
                        {
                            return(EvaluationResult.Create(ToStringConverter.ObjectToString(context, left) + rightString));
                        }

                        // Expecting numbers, but can't report type mismatch error, because in this case string or number are allowed.
                        if (TryGetNumbers(left, right, out leftNumber, out rightNumber))
                        {
                            return(EvaluationResult.Create(leftNumber + rightNumber));
                        }

                        context.Errors.ReportUnexpectedValueType(env, LeftExpression, left, typeof(int), typeof(string));
                        return(EvaluationResult.Error);

                    // Math operators
                    case BinaryOperator.Remainder:
                        return(EvaluationResult.Create(Converter.ExpectNumber(left, position: 0) % Converter.ExpectNumber(right, position: 1)));

                    case BinaryOperator.Multiplication:
                        return(EvaluationResult.Create(Converter.ExpectNumber(left, position: 0) * Converter.ExpectNumber(right, position: 1)));

                    case BinaryOperator.Subtraction:
                        return(EvaluationResult.Create(Converter.ExpectNumber(left, position: 0) - Converter.ExpectNumber(right, position: 1)));

                    case BinaryOperator.Exponentiation:
                        return(NumberOperations.Power(context, Converter.ExpectNumber(left), Converter.ExpectNumber(right), LocationForLogging(context, env)));

                    // Equality + Comparison
                    case BinaryOperator.Equal:
                        return(EvaluationResult.Create(left.Equals(right)));

                    case BinaryOperator.NotEqual:
                        return(EvaluationResult.Create(!left.Equals(right)));

                    case BinaryOperator.GreaterThanOrEqual:
                        return(EvaluationResult.Create(Converter.ExpectNumber(left, position: 0) >= Converter.ExpectNumber(right, position: 1)));

                    case BinaryOperator.GreaterThan:
                        return(EvaluationResult.Create(Converter.ExpectNumber(left, position: 0) > Converter.ExpectNumber(right, position: 1)));

                    case BinaryOperator.LessThanOrEqual:
                        return(EvaluationResult.Create(Converter.ExpectNumber(left, position: 0) <= Converter.ExpectNumber(right, position: 1)));

                    case BinaryOperator.LessThan:
                        return(EvaluationResult.Create(Converter.ExpectNumber(left, position: 0) < Converter.ExpectNumber(right, position: 1)));

                    // Conditionals
                    case BinaryOperator.Or:
                        return(EvalOr(context, env, frame, left));

                    case BinaryOperator.And:
                        return(EvalAnd(context, env, frame, left));

                    // Bitwise operations
                    // For all bitwise operations call to ToEnumValueIfNeeded is required to convert
                    // numeric representation to enum value if left hand side is enum
                    // (ExpectNumberOrEnums will make sure that left and right operands have the same type).
                    case BinaryOperator.BitWiseOr:
                        if (ExpectNumbersOrEnums(context, env, left, right, out leftNumber, out rightNumber))
                        {
                            return(Converter.ToEnumValueIfNeeded(left.GetType(), leftNumber | rightNumber));
                        }

                        return(EvaluationResult.Error);

                    case BinaryOperator.BitWiseAnd:
                        if (ExpectNumbersOrEnums(context, env, left, right, out leftNumber, out rightNumber))
                        {
                            return(Converter.ToEnumValueIfNeeded(left.GetType(), leftNumber & rightNumber));
                        }

                        return(EvaluationResult.Error);

                    case BinaryOperator.BitWiseXor:
                        if (ExpectNumbersOrEnums(context, env, left, right, out leftNumber, out rightNumber))
                        {
                            return(Converter.ToEnumValueIfNeeded(left.GetType(), leftNumber ^ rightNumber));
                        }

                        break;

                    case BinaryOperator.LeftShift:
                        return(EvaluationResult.Create(Converter.ExpectNumber(left, position: 0) << Converter.ExpectNumber(right, position: 1)));

                    case BinaryOperator.SignPropagatingRightShift:
                        return(EvaluationResult.Create(NumberOperations.SignPropagatingRightShift(
                                                           Converter.ExpectNumber(left, position: 0),
                                                           Converter.ExpectNumber(right, position: 1)).Value));

                    case BinaryOperator.ZeroFillingRightShift:
                        return(EvaluationResult.Create(NumberOperations.ZeroFillingRightShift(
                                                           Converter.ExpectNumber(left, position: 0),
                                                           Converter.ExpectNumber(right, position: 1)).Value));

                    default:
                        // And and Or operator should have been replaced by the ite expression.
                        // case BinaryOperator.And:
                        // case BinaryOperator.Or:
                        //    return (bool)l && (bool)RightExpression.Eval(context, env, frame);
                        //    return (bool) l || (bool) RightExpression.Eval(context, env, frame);
                        Contract.Assert(false);
                        break;
                    }
                }
            }
            catch (OverflowException)
            {
                context.Logger.ReportArithmeticOverflow(
                    context.LoggingContext,
                    LocationForLogging(context, env),
                    this.ToDisplayString(context));
            }
            catch (ConvertException convertException)
            {
                context.Errors.ReportUnexpectedValueType(
                    env,
                    convertException.ErrorContext.Pos == 0 ? LeftExpression : RightExpression,
                    convertException.Value, convertException.ExpectedTypesToString(context));
            }
            catch (DivideByZeroException)
            {
                context.Errors.ReportDivideByZeroException(env, this, Location);
            }

            return(EvaluationResult.Error);
        }
Beispiel #7
0
 public override bool Interpret(Context context)
 {
     return(LeftExpression.Interpret(context) && RightExpression.Interpret(context));
 }
 public override object Clone()
 {
     return(new SCIMLogicalExpression(LogicalOperator, (SCIMExpression)LeftExpression.Clone(), (SCIMExpression)RightExpression.Clone()));
 }
Beispiel #9
0
 public override string ToString() => $"{LeftExpression.ToString()} {Op.ToString()} {RightExpression.ToString()}";
Beispiel #10
0
 public override double Interpret(Context context)
 {
     return(LeftExpression.Interpret(context) / RightExpression.Interpret(context));
 }
        public override Type EvaluateType()
        {
            var  leftType         = LeftExpression.EvaluateType();
            var  rightType        = RightExpression.EvaluateType();
            var  leftTypeUnboxed  = TypeHelper.GetUnderlyingTypeIfNullable(leftType);
            var  rightTypeUnboxed = TypeHelper.GetUnderlyingTypeIfNullable(rightType);
            var  anyNullable      = TypeHelper.IsSystemNullableType(leftType) || TypeHelper.IsSystemNullableType(rightType);
            Type resultedTypeRaw;

            switch (Operator.Type)
            {
            case BinaryOperatorType.Logical:
                // For logical comparison, we ensure that all operands' type are logical already
                // The return type is always boolean (logical)
                if ((leftType != typeof(bool) && leftType != typeof(bool?)) ||
                    (rightType != typeof(bool) && rightType != typeof(bool?)))
                {
                    throw new TranspilerNotSupportedException($"Logical binary operator {Operator} operating must operate on bool types. Actual types: {leftType}, {rightType}");
                }
                return(anyNullable ? TypeHelper.MakeNullableIfNotAlready(typeof(bool)) : typeof(bool));

            case BinaryOperatorType.Value:
                // For value type operator, use the value type coercion table
                if (!TypeCoersionTables.CoersionTableForValueType.TryGetValue((Operator.Name, leftTypeUnboxed, rightTypeUnboxed), out resultedTypeRaw))
                {
                    throw new TranspilerInternalErrorException($"Unexpected use of binary operator {Operator.Name} operating between types {leftTypeUnboxed} and {rightTypeUnboxed}");
                }
                if (resultedTypeRaw == default(Type))
                {
                    throw new TranspilerNotSupportedException($"Binary operator {Operator.Name} operating between types {leftTypeUnboxed} and {rightTypeUnboxed}");
                }
                return(anyNullable ? TypeHelper.MakeNullableIfNotAlready(resultedTypeRaw) : resultedTypeRaw);

            case BinaryOperatorType.Comparison:
                // For comparison operators, use the equality/inequality type coercion table
                if (Operator.Name == BinaryOperator.EQ || Operator.Name == BinaryOperator.NEQ)
                {
                    if (!TypeCoersionTables.CoersionTableEqualityComparison.TryGetValue((leftTypeUnboxed, rightTypeUnboxed), out resultedTypeRaw))
                    {
                        throw new TranspilerInternalErrorException($"Unexpected use of (un)equality operator {Operator.Name} operating between types {leftTypeUnboxed} and {rightTypeUnboxed}");
                    }
                }
                else if (Operator.Name == BinaryOperator.IN)
                {
                    // IN need special handling as right operand is a list
                    var innerTypes = rightTypeUnboxed.GetGenericArguments();
                    if (innerTypes == null || innerTypes.Length != 1)
                    {
                        throw new TranspilerInternalErrorException($"Unexpected use of IN operator, the right type {rightTypeUnboxed} is not a list of value type");
                    }
                    resultedTypeRaw = typeof(bool);
                }
                else
                {
                    if (!TypeCoersionTables.CoersionTableDefaultComparison.TryGetValue((leftTypeUnboxed, rightTypeUnboxed), out resultedTypeRaw))
                    {
                        throw new TranspilerInternalErrorException($"Unexpected use of binary operator {Operator.Name} operating between types {leftTypeUnboxed} and {rightTypeUnboxed}");
                    }
                }
                if (resultedTypeRaw == default(Type))
                {
                    throw new TranspilerNotSupportedException($"Binary operator {Operator.Name} operating between types {leftTypeUnboxed} and {rightTypeUnboxed}");
                }
                return(anyNullable ? TypeHelper.MakeNullableIfNotAlready(resultedTypeRaw) : resultedTypeRaw);

            case BinaryOperatorType.Invalid:
            default:
                throw new TranspilerInternalErrorException($"Unexpected operator type: {Operator.Type}");
            }
        }
 public override object Clone()
 {
     return(new SCIMComparisonExpression(ComparisonOperator, (SCIMAttributeExpression)LeftExpression.Clone(), Value));
 }
Beispiel #13
0
 public override bool Eval(PCBObject Obj)
 {
     return(LeftExpression.Eval(Obj) ^ RightExpression.Eval(Obj));
 }
Beispiel #14
0
 public override string Template()
 {
     return($"{LeftExpression.Template()}\n{AssignmentTemplate}\n{LeftExpression.Save()}");
 }
Beispiel #15
0
 /// <inheritdoc />
 protected override void DoSerialize(BuildXLWriter writer)
 {
     LeftExpression.Serialize(writer);
     writer.Write((byte)OperatorKind);
     RightExpression.Serialize(writer);
 }
 public Expression Generate(Parameter parameter, LeftExpression left, RightExpression right, FilterAttribute filterAttribute, object value)
 {
     return(Expression.NotEqual(left.GetExpression(), right.GetExpression()));
 }
Beispiel #17
0
 /// <inheritdoc />
 public override string ToDebugString()
 {
     return(I($"{LeftExpression.ToDebugString()} {OperatorKind.ToDisplayString()} {RightExpression.ToDebugString()}"));
 }
 public override int AbsoluteValue()
 {
     return(LeftExpression.AbsoluteValue() + RightExpression.AbsoluteValue());
 }
Beispiel #19
0
 public override bool Eval(IPrincipal principal)
 {
     return(LeftExpression.Eval(principal) || RightExpression.Eval(principal));
 }
Beispiel #20
0
 public override string Template()
 {
     return($"{LeftExpression.Template()}\nmovq\t%rax,%rcx\n{RightExpression.Template()}\n{AssignmentTemplate}\n{LeftExpression.Save()}");
 }
Beispiel #21
0
 public override QValue Evaluate()
 {
     return(((IntValue)LeftExpression.Evaluate()).GrTh((IntValue)RightExpression.Evaluate()));
 }
Beispiel #22
0
 public override double Evaluate()
 {
     return(Math.Atan2(LeftExpression.Evaluate(), RightExpression.Evaluate()));
 }
Beispiel #23
0
 public override QValue Evaluate()
 {
     return(((BoolValue)LeftExpression.Evaluate()).And((BoolValue)RightExpression.Evaluate()));
 }
Beispiel #24
0
 public override double Evaluate()
 {
     return(LeftExpression.Evaluate() + RightExpression.Evaluate());
 }
 public override Expression Clone()
 {
     return(new SpatialAnalysisGeometricExpression((GeometryExpression)LeftExpression.Clone(), SpatialAnalysisOperator,
                                                   (GeometryExpression)RightExpression.Clone()));
 }
Beispiel #26
0
 public override Expression Clone()
 {
     return(new SpatialAnalysisDistanceExpression((GeometryExpression)LeftExpression.Clone(),
                                                  (GeometryExpression)RightExpression.Clone()));
 }
Beispiel #27
0
 public override object Evaluate()
 {
     return((Complex)Combinatorics.Permutations(LeftExpression.EvaluateAsInt32(), RightExpression.EvaluateAsInt32()));
 }
Beispiel #28
0
        /// <summary>
        /// Evaluates filter expression agains message context
        /// </summary>
        /// <param name="messageContext">Key value pair store with message context</param>
        /// <returns>Evaluation result task</returns>
        public async Task <IComparable> EvaluateAsync(IReadOnlyDictionary <string, object> messageContext)
        {
            // When no actual filter was created as expression we think that evaluation passed successfully, because there were nothing to compare to
            if (Operation == 0 && (LeftExpression == null || RightExpression == null))
            {
                return(true);
            }

            var left  = LeftExpression.EvaluateAsync(messageContext);
            var right = RightExpression.EvaluateAsync(messageContext);

            await Task.WhenAll(left, right);

            if (object.ReferenceEquals(left.Result, NullEvaluationResult.Value))
            {
                return(false);
            }

            //actual operation between left and right
            switch (Operation)
            {
            case FilterOperator.And:
            {
                return((bool)left.Result && (bool)right.Result);
            }

            case FilterOperator.Or:
            {
                return((bool)left.Result || (bool)right.Result);
            }

            case FilterOperator.EqualTo:
            {
                return(left.Result.Equals(right.Result));
            }

            case FilterOperator.NotEqualTo:
            {
                return(!left.Result.Equals(right.Result));
            }

            case FilterOperator.GreaterThan:
            {
                return(left.Result.CompareTo(right.Result) == 1);
            }

            case FilterOperator.GreaterThanOrEqualTo:
            {
                return(left.Result.CompareTo(right.Result) >= 0);
            }

            case FilterOperator.LessThanOrEqualTo:
            {
                return(left.Result.CompareTo(right.Result) <= 0);
            }

            case FilterOperator.LessThan:
            {
                return(left.Result.CompareTo(right.Result) == -1);
            }
            }
            return(false);
        }