Ejemplo n.º 1
0
        internal override object Eval()
        {
            var left  = LeftOperand.Eval();
            var right = RightOperand.Eval();

            if (left is double lDbl && right is double rDbl)
            {
                return(lDbl - rDbl);
            }
            if (left is bool lBool && right is bool rBool)
            {
                return((lBool ? 1 : 0) - (rBool ? 1 : 0));                                              // Maybe throw an exception instead?
            }
            if (left is bool lBool2 && right is double rDbl2)
            {
                return((lBool2 ? 1 : 0) - rDbl2);
            }
            if (left is double lDbl2 && right is bool rBool2)
            {
                return(lDbl2 - (rBool2 ? 1 : 0));
            }
            return(left.ToString().Replace(right.ToString(), ""));   //Interesting concept... I wonder if other languages do this?
        }
Ejemplo n.º 2
0
        public override void Generate(CodeGenerator cg)
        {
            Label ret1 = cg.generator.DefineLabel();
            Label end  = cg.generator.DefineLabel();

            LeftOperand.Generate(cg);
            RightOperand.Generate(cg);

            if (LeftOperand.returnType.isString)
            {
                cg.generator.Emit(OpCodes.Call, typeof(string).GetMethod("Compare", new Type[] { typeof(string), typeof(string) }));
                cg.generator.Emit(OpCodes.Ldc_I4_0);
            }
            cg.generator.Emit(OperatorOpCode, ret1);

            cg.generator.Emit(OpCodes.Ldc_I4_0);
            cg.generator.Emit(OpCodes.Br, end);

            cg.generator.MarkLabel(ret1);
            cg.generator.Emit(OpCodes.Ldc_I4_1);

            cg.generator.MarkLabel(end);
        }
Ejemplo n.º 3
0
        internal override object Eval()
        {
            var left  = LeftOperand.Eval();
            var right = RightOperand.Eval();

            if (left is double lDbl && right is double rDbl)
            {
                return(lDbl * rDbl);
            }
            if (left is bool lBool && right is bool rBool)
            {
                return((lBool ? 1 : 0) * (rBool ? 1 : 0));
            }
            if (left is bool lBool2 && right is double rDbl2)
            {
                return((lBool2 ? 1 : 0) * rDbl2);
            }
            if (left is double lDbl2 && right is bool rBool2)
            {
                return(lDbl2 * (rBool2 ? 1 : 0));
            }
            throw new InvalidOperationException($"Multiplication can not be performed on the operands [{left}] and [{right}]");
        }
Ejemplo n.º 4
0
        public override BaseType ValidateSemantic()
        {
            var leftType  = LeftOperand.ValidateSemantic();
            var rightType = RightOperand.ValidateSemantic();

            if (leftType is IntType && rightType is IntType)
            {
                return(leftType);
            }
            if (leftType is StringType && rightType is StringType)
            {
                return(leftType);
            }
            if (leftType is IntType && rightType is StringType)
            {
                return(rightType);
            }
            if (leftType is StringType && rightType is IntType)
            {
                return(leftType);
            }
            throw new SemanticException($"add is not supported for {leftType} and {rightType}");
        }
Ejemplo n.º 5
0
        internal override object Eval()
        {
            var left  = LeftOperand.Eval();
            var right = RightOperand.Eval();

            if (left is double lDbl && right is double rDbl)
            {
                return(lDbl + rDbl);
            }
            if (left is bool lBool && right is bool rBool)
            {
                return((lBool ? 1 : 0) + (rBool ? 1 : 0));
            }
            if (left is bool lBool2 && right is double rDbl2)
            {
                return((lBool2 ? 1 : 0) + rDbl2);
            }
            if (left is double lDbl2 && right is bool rBool2)
            {
                return(lDbl2 + (rBool2 ? 1 : 0));
            }
            return(left.ToString() + right.ToString());
        }
Ejemplo n.º 6
0
        public override DataType staticTypeCheck()
        {
            DataType leftType  = LeftOperand.staticTypeCheck();
            DataType rightType = RightOperand.staticTypeCheck();

            if (leftType == DataType.StringType && rightType == DataType.StringType)
            {
                return(DataType.StringType);
            }

            else if (leftType == DataType.FloatType || rightType == DataType.FloatType)
            {
                return(DataType.FloatType);
            }

            else if (leftType == DataType.IntegerType && rightType == DataType.IntegerType)
            {
                return(DataType.IntegerType);
            }

            Log.Error("Type mismatch", Filename, Line, Position);
            return(DataType.NoneType);
        }
Ejemplo n.º 7
0
 protected BinaryRelationship ComputeTransitiveRelationship(BinaryRelationship other, BinaryRelationship factory)
 {
     if (LeftOperand.Equals(other.LeftOperand))
     {
         return(factory.CreateNew(RightOperand, other.RightOperand));
     }
     else if (RightOperand.Equals(other.LeftOperand))
     {
         return(factory.CreateNew(LeftOperand, other.RightOperand));
     }
     else if (LeftOperand.Equals(other.RightOperand))
     {
         return(factory.CreateNew(other.LeftOperand, RightOperand));
     }
     else if (RightOperand.Equals(other.RightOperand))
     {
         return(factory.CreateNew(other.LeftOperand, LeftOperand));
     }
     else
     {
         return(null);
     }
 }
 private BinaryRelationship GetTransitiveRelationship(EqualsRelationship other)
 {
     if (LeftOperand.Equals(other.LeftOperand))
     {
         return(new ComparisonRelationship(ComparisonKind, other.RightOperand, RightOperand));
     }
     else if (RightOperand.Equals(other.LeftOperand))
     {
         return(new ComparisonRelationship(ComparisonKind, LeftOperand, other.RightOperand));
     }
     else if (LeftOperand.Equals(other.RightOperand))
     {
         return(new ComparisonRelationship(ComparisonKind, other.LeftOperand, RightOperand));
     }
     else if (RightOperand.Equals(other.RightOperand))
     {
         return(new ComparisonRelationship(ComparisonKind, LeftOperand, other.LeftOperand));
     }
     else
     {
         return(null);
     }
 }
Ejemplo n.º 9
0
        public override void GenerateCode(ILGenerator gen, CodeFlow cf)
        {
            CodeFlow.LoadEvaluationContext(gen);
            var leftDesc  = LeftOperand.ExitDescriptor;
            var rightDesc = RightOperand.ExitDescriptor;
            var leftPrim  = CodeFlow.IsValueType(leftDesc);
            var rightPrim = CodeFlow.IsValueType(rightDesc);

            cf.EnterCompilationScope();
            LeftOperand.GenerateCode(gen, cf);
            cf.ExitCompilationScope();
            if (leftPrim)
            {
                CodeFlow.InsertBoxIfNecessary(gen, leftDesc);
            }

            cf.EnterCompilationScope();
            RightOperand.GenerateCode(gen, cf);
            cf.ExitCompilationScope();
            if (rightPrim)
            {
                CodeFlow.InsertBoxIfNecessary(gen, rightDesc);
            }

            // returns bool
            gen.Emit(OpCodes.Call, _equalityCheck);

            // Invert the boolean
            var result = gen.DeclareLocal(typeof(bool));

            gen.Emit(OpCodes.Ldc_I4_0);
            gen.Emit(OpCodes.Ceq);
            gen.Emit(OpCodes.Stloc, result);
            gen.Emit(OpCodes.Ldloc, result);

            cf.PushDescriptor(TypeDescriptor.Z);
        }
        public override void CheckSemantic(SymbolTable symbolTable, List <CompileError> errors)
        {
            ///check semantics al operando izquierdo
            LeftOperand.CheckSemantic(symbolTable, errors);

            ///check semantics al operando derecho
            RightOperand.CheckSemantic(symbolTable, errors);

            ///si alguno de los operandos evalúa de error este nodo también
            if (Object.Equals(LeftOperand.NodeInfo, SemanticInfo.SemanticError) ||
                Object.Equals(RightOperand.NodeInfo, SemanticInfo.SemanticError))
            {
                ///el nodo evalúa de error
                NodeInfo = SemanticInfo.SemanticError;
                return;
            }

            //los operandos tienen que ser compatibles
            if (!LeftOperand.NodeInfo.Type.IsCompatibleWith(RightOperand.NodeInfo.Type))
            {
                errors.Add(new CompileError
                {
                    Line         = LeftOperand.Line,
                    Column       = LeftOperand.CharPositionInLine,
                    ErrorMessage = string.Format("Operand '{0}' cannot be applied to operands of type '{1}' and '{2}'", this.Text, LeftOperand.NodeInfo.Type.Name, RightOperand.NodeInfo.Type.Name),
                    Kind         = ErrorKind.Semantic
                });

                ///el nodo evalúa de error
                NodeInfo = SemanticInfo.SemanticError;
            }

            ///seteamos la información del NodeInfo
            NodeInfo.BuiltInType = BuiltInType.Int;
            NodeInfo.Type        = SemanticInfo.Int;
            NodeInfo.ILType      = typeof(int);
        }
Ejemplo n.º 11
0
        public override IEnumerable <ProgramState> TrySetConstraint(SymbolicValueConstraint constraint, ProgramState programState)
        {
            var boolConstraint = constraint as BoolConstraint;

            if (boolConstraint == null)
            {
                return(new[] { programState });
            }

            if (constraint == BoolConstraint.False)
            {
                return(ThrowIfTooMany(
                           LeftOperand.TrySetConstraint(BoolConstraint.False, programState)
                           .SelectMany(ps => RightOperand.TrySetConstraint(BoolConstraint.False, ps))));
            }

            return(ThrowIfTooMany(
                       LeftOperand.TrySetConstraint(BoolConstraint.True, programState)
                       .SelectMany(ps => RightOperand.TrySetConstraint(BoolConstraint.False, ps))
                       .Union(LeftOperand.TrySetConstraint(BoolConstraint.False, programState)
                              .SelectMany(ps => RightOperand.TrySetConstraint(BoolConstraint.True, ps)))
                       .Union(LeftOperand.TrySetConstraint(BoolConstraint.True, programState)
                              .SelectMany(ps => RightOperand.TrySetConstraint(BoolConstraint.True, ps)))));
        }
Ejemplo n.º 12
0
        public override ExpressionCode GenerateCode()
        {
            var leftType  = LeftOperand.GenerateCode().Type;
            var rightType = RightOperand.GenerateCode().Type;

            if (leftType != null && rightType != null)
            {
                if (leftType == "float" || rightType == "float")
                {
                    var s = " ( getFloatMultValue( " + LeftOperand.GenerateCode().Code + " , " +
                            RightOperand.GenerateCode().Code + " ) )";

                    return(new ExpressionCode {
                        Code = s, Type = "float"
                    });
                }
                var stringCode = "( getIntMultValue( " + LeftOperand.GenerateCode().Code + " , " +
                                 RightOperand.GenerateCode().Code + " ) )";
                return(new ExpressionCode {
                    Code = stringCode, Type = "int"
                });
            }
            throw new GenerationException("Cannot generate code from null type operand");
        }
Ejemplo n.º 13
0
        public override void Generate(CodeGenerator cg)
        {
            Label push_false = cg.generator.DefineLabel();
            Label end        = cg.generator.DefineLabel();

            LeftOperand.Generate(cg);
            cg.generator.Emit(OpCodes.Ldc_I4_0);
            cg.generator.Emit(OpCodes.Beq, push_false);

            //el primer operando era verdadero
            RightOperand.Generate(cg);
            cg.generator.Emit(OpCodes.Ldc_I4_0);
            cg.generator.Emit(OpCodes.Beq, push_false);

            //el segundo operando era verdadero
            cg.generator.Emit(OpCodes.Ldc_I4_1);
            cg.generator.Emit(OpCodes.Br, end);

            //el primer operando es falso
            cg.generator.MarkLabel(push_false);
            cg.generator.Emit(OpCodes.Ldc_I4_0);

            cg.generator.MarkLabel(end);
        }
Ejemplo n.º 14
0
        public override void GenerateCode(ILGenerator gen, CodeFlow cf)
        {
            LeftOperand.GenerateCode(gen, cf);
            var leftDesc = LeftOperand.ExitDescriptor;
            var exitDesc = _exitTypeDescriptor;

            if (exitDesc == null)
            {
                throw new InvalidOperationException("No exit type descriptor");
            }

            CodeFlow.InsertNumericUnboxOrPrimitiveTypeCoercion(gen, leftDesc, exitDesc);
            if (_children.Length > 1)
            {
                cf.EnterCompilationScope();
                RightOperand.GenerateCode(gen, cf);
                var rightDesc = RightOperand.ExitDescriptor;
                cf.ExitCompilationScope();
                CodeFlow.InsertNumericUnboxOrPrimitiveTypeCoercion(gen, rightDesc, exitDesc);
                gen.Emit(OpCodes.Rem);
            }

            cf.PushDescriptor(_exitTypeDescriptor);
        }
Ejemplo n.º 15
0
        public override IQueryElement VisitWhere_operation([NotNull] QueryGrammarParser.Where_operationContext context)
        {
            IQueryElement leftValueTree = Visit(context.left);

            if (context.where_operator().is_null() != null)
            {
                OperationIsNull isNullTree = new OperationIsNull();
                isNullTree.Add(leftValueTree);
                return(isNullTree);
            }
            else if (context.where_operator().is_not_null() != null)
            {
                OperationIsNotNull isNotNullTree = new OperationIsNotNull();
                isNotNullTree.Add(leftValueTree);
                return(isNotNullTree);
            }

            OperationComperision comperasionTree = new OperationComperision();

            LeftOperand left = new LeftOperand();

            left.Add(leftValueTree);
            comperasionTree.Add(left);

            IQueryElement operatorTree = Visit(context.where_operator().comparison_operator());

            comperasionTree.Add(operatorTree);

            RightOperand  right          = new RightOperand();
            IQueryElement rightValueTree = Visit(context.right);

            right.Add(rightValueTree);
            comperasionTree.Add(right);

            return(comperasionTree);
        }
Ejemplo n.º 16
0
 protected bool AreOperandsMatching(BinaryRelationship rel2)
 {
     return(LeftOperand.Equals(rel2.LeftOperand) && RightOperand.Equals(rel2.RightOperand) ||
            RightOperand.Equals(rel2.LeftOperand) && LeftOperand.Equals(rel2.RightOperand));
 }
Ejemplo n.º 17
0
 public override double Compute(IReadOnlyDictionary <string, double> variableValues) => LeftOperand.Compute(variableValues) * RightOperand.Compute(variableValues);
 /// <summary>
 /// Calculates the result of the binary operation.
 /// </summary>
 /// <param name="evalContext">Evaluation context</param>
 /// <returns>Result of the operation</returns>
 public override ushort Calculate(IEvaluationContext evalContext)
 => (ushort)(LeftOperand.Evaluate(evalContext)
             & RightOperand.Evaluate(evalContext));
Ejemplo n.º 19
0
 public override string ToString()
 {
     return(String.Format("({0} \u2227 {1})", LeftOperand.ToString(), RightOperand.ToString()));
 }
Ejemplo n.º 20
0
 internal bool AreOperandsMatching(BinaryRelationship other)
 {
     return(LeftOperand.Equals(other.LeftOperand) && RightOperand.Equals(other.RightOperand) ||
            RightOperand.Equals(other.LeftOperand) && LeftOperand.Equals(other.RightOperand));
 }
Ejemplo n.º 21
0
        protected override Type ResolveInternal(Context ctx, bool mustReturn)
        {
            var leftType  = LeftOperand.Resolve(ctx);
            var rightType = RightOperand.Resolve(ctx);

            var result = ResolveOperatorType(ctx, leftType, rightType);

            if (result != null)
            {
                return(result);
            }

            if (OverloadedMethodName != null)
            {
                try
                {
                    OverloadedMethod = ctx.ResolveMethod(leftType, OverloadedMethodName, new[] { leftType, rightType });
                }
                catch
                {
                    try
                    {
                        OverloadedMethod = ctx.ResolveMethod(rightType, OverloadedMethodName, new[] { leftType, rightType });
                    }
                    catch
                    {
                    }
                }

                // cannot be generic
                if (OverloadedMethod != null)
                {
                    return(OverloadedMethod.ReturnType);
                }
            }

            if (IsNumericOperator)
            {
                if (leftType.IsNullableType() || rightType.IsNullableType())
                {
                    var leftNullable  = leftType.IsNullableType() ? leftType.GetGenericArguments()[0] : leftType;
                    var rightNullable = rightType.IsNullableType() ? rightType.GetGenericArguments()[0] : rightType;

                    var commonNumericType = TypeExtensions.GetNumericOperationType(leftNullable, rightNullable);
                    if (commonNumericType == null)
                    {
                        Error(CompilerMessages.OperatorTypesSignednessMismatch);
                    }

                    return(typeof(Nullable <>).MakeGenericType(commonNumericType));
                }

                if (leftType.IsNumericType() && rightType.IsNumericType())
                {
                    var commonNumericType = TypeExtensions.GetNumericOperationType(leftType, rightType);
                    if (commonNumericType == null)
                    {
                        Error(CompilerMessages.OperatorTypesSignednessMismatch);
                    }

                    return(commonNumericType);
                }
            }

            Error(this, CompilerMessages.OperatorBinaryTypesMismatch, OperatorRepresentation, leftType, rightType);
            return(null);
        }
Ejemplo n.º 22
0
 public override double Evaluate()
 {
     return(LeftOperand.Evaluate() - RightOperand.Evaluate());
 }
Ejemplo n.º 23
0
        /// <summary>Creates a string representation of this binary operator.</summary>
        /// <returns>String representation of this binary operator.</returns>
        public override string ToString()
        {
            string operatorString = Member.ToString();

            switch (Member)
            {
            case MethodNames.Add:
                operatorString = "+";
                break;

            case MethodNames.AddAndAssign:
                operatorString = "+=";
                break;

            case MethodNames.Substract:
                operatorString = "-";
                break;

            case MethodNames.SubstractAndAssign:
                operatorString = "-=";
                break;

            case MethodNames.Multiply:
                operatorString = "*";
                break;

            case MethodNames.MultiplyAndAssign:
                operatorString = "*=";
                break;

            case MethodNames.Divide:
                operatorString = "/";
                break;

            case MethodNames.DivideAndAssign:
                operatorString = "/=";
                break;

            case MethodNames.Modulo:
                operatorString = "%";
                break;

            case MethodNames.ModuloAndAssign:
                operatorString = "%=";
                break;

            case MethodNames.Equal:
                operatorString = "==";
                break;

            case MethodNames.NotEqual:
                operatorString = "!=";
                break;

            case MethodNames.GreaterThan:
                operatorString = ">";
                break;

            case MethodNames.GreaterThanOrEqual:
                operatorString = ">=";
                break;

            case MethodNames.LessThan:
                operatorString = "<";
                break;

            case MethodNames.LessThanOrEqual:
                operatorString = "<=";
                break;

            case MethodNames.BitwiseAnd:
                operatorString = "&";
                break;

            case MethodNames.BitwiseAndAndAssign:
                operatorString = "&=";
                break;

            case MethodNames.BitwiseOr:
                operatorString = "|";
                break;

            case MethodNames.BitwiseOrAndAssign:
                operatorString = "|=";
                break;

            case MethodNames.BitwiseXor:
                operatorString = "^";
                break;

            case MethodNames.BitwiseXorAndAssign:
                operatorString = "^=";
                break;

            case MethodNames.BitwiseNot:
                operatorString = "~";
                break;

            case MethodNames.BitwiseNotAndAssign:
                operatorString = "~=";
                break;

            case MethodNames.And:
                operatorString = "&&";
                break;

            case MethodNames.Or:
                operatorString = "||";
                break;

            case MethodNames.Xor:
                operatorString = "^^";
                break;

            case MethodNames.BitwiseShiftLeft:
                operatorString = "<<";
                break;

            case MethodNames.BitwiseShiftLeftAndAssign:
                operatorString = "<<=";
                break;

            case MethodNames.BitwiseShiftRight:
                operatorString = ">>";
                break;

            case MethodNames.BitwiseShiftRightAndAssign:
                operatorString = ">>=";
                break;
            }

            return(System.String.Format(
                       "{0}{1}{2}",
                       LeftOperand != null ? LeftOperand.ToString() : System.String.Empty,
                       operatorString,
                       RightOperand != null ? RightOperand.ToString() : System.String.Empty));
        }
Ejemplo n.º 24
0
 /// <summary>Serves as the default hash function.</summary>
 /// <returns>Type: <see cref="System.Int32" />
 /// A hash code for the current object.</returns>
 public override int GetHashCode()
 {
     return(typeof(BinaryOperator).FullName.GetHashCode() ^ (LeftOperand != null ? LeftOperand.GetHashCode() : 0) ^ (RightOperand != null ? RightOperand.GetHashCode() : 0));
 }
Ejemplo n.º 25
0
 /// <summary>Determines whether the specified object is equal to the current object.</summary>
 /// <param name="operand">Type: <see cref="System.Object" />
 /// The object to compare with the current object.</param>
 /// <returns>Type: <see cref="System.Boolean" />
 /// <b>true</b> if the specified object is equal to the current object; otherwise, <b>false</b>.</returns>
 public override bool Equals(object operand)
 {
     return((!Object.Equals(operand, null)) && (operand.GetType() == typeof(BinaryOperator)) &&
            (LeftOperand != null ? LeftOperand.Equals(((BinaryOperator)operand).LeftOperand) : Object.Equals(((BinaryOperator)operand).LeftOperand, null)) &&
            (RightOperand != null ? RightOperand.Equals(((BinaryOperator)operand).RightOperand) : Object.Equals(((BinaryOperator)operand).RightOperand, null)));
 }
Ejemplo n.º 26
0
        /// <summary>
        /// Emits code for equality and inequality comparison.
        /// </summary>
        private void EmitEqualityComparison(Context ctx, Type left, Type right)
        {
            var gen = ctx.CurrentMethod.Generator;

            // compare two strings
            if (left == right && left == typeof(string))
            {
                LeftOperand.Emit(ctx, true);
                RightOperand.Emit(ctx, true);

                var method = typeof(string).GetMethod("Equals", new[] { typeof(string), typeof(string) });
                gen.EmitCall(method);

                if (Kind == ComparisonOperatorKind.NotEquals)
                {
                    EmitInversion(gen);
                }

                return;
            }

            // compare primitive types
            if ((left.IsNumericType() && right.IsNumericType()) || (left == right && left == typeof(bool)))
            {
                if (left == typeof(bool))
                {
                    LeftOperand.Emit(ctx, true);
                    RightOperand.Emit(ctx, true);
                }
                else
                {
                    LoadAndConvertNumerics(ctx);
                }

                gen.EmitCompareEqual();

                if (Kind == ComparisonOperatorKind.NotEquals)
                {
                    EmitInversion(gen);
                }

                return;
            }

            // compare nullable against another nullable, it's base type or null
            if (left.IsNullableType())
            {
                if (left == right || Nullable.GetUnderlyingType(left) == right)
                {
                    EmitNullableComparison(ctx, LeftOperand, RightOperand);
                }
                else if (right == typeof(NullType))
                {
                    EmitHasValueCheck(ctx, LeftOperand);
                }

                return;
            }

            if (right.IsNullableType())
            {
                if (Nullable.GetUnderlyingType(right) == left)
                {
                    EmitNullableComparison(ctx, RightOperand, LeftOperand);
                }
                else if (left == typeof(NullType))
                {
                    EmitHasValueCheck(ctx, RightOperand);
                }

                return;
            }

            // compare a reftype against a null
            if (left == typeof(NullType) || right == typeof(NullType))
            {
                LeftOperand.Emit(ctx, true);
                RightOperand.Emit(ctx, true);
                gen.EmitCompareEqual();

                if (Kind == ComparisonOperatorKind.NotEquals)
                {
                    EmitInversion(gen);
                }

                return;
            }

            if (left is TypeBuilder && left == right)
            {
                var equals = ctx.ResolveMethod(left, "Equals", new[] { typeof(object) });

                LeftOperand.Emit(ctx, true);
                RightOperand.Emit(ctx, true);

                gen.EmitCall(equals.MethodInfo);

                if (Kind == ComparisonOperatorKind.NotEquals)
                {
                    EmitInversion(gen);
                }

                return;
            }

            throw new ArgumentException("Unknown types to compare!");
        }
Ejemplo n.º 27
0
 /// <summary>
 /// Returns a <see cref="System.String" /> that represents this instance.
 /// </summary>
 /// <returns>
 /// A <see cref="System.String" /> that represents this instance.
 /// </returns>
 public override string ToString()
 {
     return(string.Format("({0}) OR ({1})",
                          LeftOperand != null ? LeftOperand.ToString() : string.Empty,
                          RightOperand != null ? RightOperand.ToString() : string.Empty));
 }
Ejemplo n.º 28
0
 public override string GenerateCode()
 {
     return($"{LeftOperand.GenerateCode()} > {RightOperand.GenerateCode()}");
 }
 internal bool AreOperandsSwapped(ComparisonRelationship rel)
 {
     return(LeftOperand.Equals(rel.RightOperand) && RightOperand.Equals(rel.LeftOperand));
 }
Ejemplo n.º 30
0
        /// <summary>
        /// Calculates the result of the binary operation.
        /// </summary>
        /// <param name="evalContext">Evaluation context</param>
        /// <returns>Result of the operation</returns>
        public override ExpressionValue Calculate(IEvaluationContext evalContext)
        {
            var left  = LeftOperand.Evaluate(evalContext);
            var right = RightOperand.Evaluate(evalContext);

            switch (right.Type)
            {
            case ExpressionValueType.Bool:
            case ExpressionValueType.Integer:
                var rightNum = right.AsLong();
                if (rightNum == 0)
                {
                    EvaluationError = DIV_BY_ZERO_ERROR;
                    return(ExpressionValue.Error);
                }
                switch (left.Type)
                {
                case ExpressionValueType.Bool:
                case ExpressionValueType.Integer:
                    return(new ExpressionValue(left.AsLong() / rightNum));

                case ExpressionValueType.Real:
                    return(new ExpressionValue(left.AsReal() / rightNum));

                case ExpressionValueType.String:
                    EvaluationError = LEFT_STRING_ERROR;
                    return(ExpressionValue.Error);

                default:
                    return(ExpressionValue.Error);
                }

            case ExpressionValueType.Real:
                var rightReal = right.AsReal();
                if (Math.Abs(rightReal) < double.Epsilon)
                {
                    EvaluationError = DIV_BY_ZERO_ERROR;
                    return(ExpressionValue.Error);
                }
                switch (left.Type)
                {
                case ExpressionValueType.Bool:
                case ExpressionValueType.Integer:
                    return(new ExpressionValue(left.AsLong() / rightReal));

                case ExpressionValueType.Real:
                    return(new ExpressionValue(left.AsReal() / rightReal));

                case ExpressionValueType.String:
                    EvaluationError = LEFT_STRING_ERROR;
                    return(ExpressionValue.Error);

                default:
                    return(ExpressionValue.Error);
                }

            case ExpressionValueType.String:
                EvaluationError = RIGHT_STRING_ERROR;
                return(ExpressionValue.Error);

            default:
                return(ExpressionValue.Error);
            }
        }