Exemple #1
0
 internal static BinaryOperatorSymbol SymbolAndStringBinaryOperator(BinaryOperatorKind kind, ref Expr left, ref Expr right, BindOptions options)
 {
     if (kind == BinaryOperatorKind.Addition)
     {
         var l = left;
         var r = right;
         if (left.Datatype.NativeType == NativeType.Symbol)
         {
             Convert(ref l, Compilation.Get(NativeType.String), options);
         }
         if (right.Datatype.NativeType == NativeType.Symbol)
         {
             Convert(ref r, Compilation.Get(NativeType.String), options);
         }
         var sym = BinaryOperatorEasyOut.ClassifyOperation(kind, l.Datatype, r.Datatype);
         if (sym != null)
         {
             left  = l;
             right = r;
             Convert(ref left, sym.TypeOfOp, options);
             Convert(ref right, sym.TypeOfOp, options);
             return(sym);
         }
     }
     return(null);
 }
Exemple #2
0
        internal static BinaryOperatorSymbol BinaryOperation(BinaryOperatorKind kind, ref Expr left, ref Expr right, BindOptions options)
        {
            var sym = BinaryOperatorEasyOut.ClassifyOperation(kind, left.Datatype, right.Datatype);

            if (options.HasFlag(BindOptions.AllowInexactComparisons) && sym != null)
            {
                switch (sym.Kind)
                {
                case BinaryOperatorKind.EqString:
                case BinaryOperatorKind.EqStringObject:
                case BinaryOperatorKind.EqObjectString:
                case BinaryOperatorKind.NeqString:
                case BinaryOperatorKind.NeqStringObject:
                case BinaryOperatorKind.NeqObjectString:
                    sym = null;
                    break;
                }
            }

            if (sym != null)
            {
                Convert(ref left, sym.TypeOfOp, options);
                Convert(ref right, sym.TypeOfOp, options);
                return(sym);
            }

            // User-defined operators
            {
                var op = UserDefinedBinaryOperator(kind, ref left, ref right, options);
                if (op != null)
                {
                    return(op);
                }
            }

            // Symbol/string operations
            {
                var op = SymbolAndStringBinaryOperator(kind, ref left, ref right, options);
                if (op != null)
                {
                    return(op);
                }
            }

            // Dynamic with usual
            if (options.HasFlag(BindOptions.AllowDynamic))
            {
                var op = DynamicBinaryOperator(kind, ref left, ref right, options);
                if (op != null)
                {
                    return(op);
                }
            }

            // Emun operations
            {
                var op = EnumBinaryOperator(kind, ref left, ref right, options);
                if (op != null)
                {
                    return(op);
                }
            }

            return(null);
        }
Exemple #3
0
        internal static BinaryOperatorSymbol BinaryOperation(BinaryOperatorKind kind, ref Expr left, ref Expr right, BindOptions options)
        {
            // When one or both of the datatypes is Usual or Object then convert to Usual and let
            // the operators in the Usual type handle the binary operation
            if (left.Datatype.IsUsualOrObject() || right.Datatype.IsUsualOrObject())
            {
                Convert(ref left, Compilation.Get(NativeType.Usual), options);
                Convert(ref right, Compilation.Get(NativeType.Usual), options);
            }
            var sym = BinaryOperatorEasyOut.ClassifyOperation(kind, left.Datatype, right.Datatype);

            if (options.HasFlag(BindOptions.AllowInexactComparisons) && sym != null)
            {
                switch (sym.Kind)
                {
                case BinaryOperatorKind.EqString:
                case BinaryOperatorKind.EqStringObject:
                case BinaryOperatorKind.EqObjectString:
                case BinaryOperatorKind.NeqString:
                case BinaryOperatorKind.NeqStringObject:
                case BinaryOperatorKind.NeqObjectString:
                    sym = null;
                    break;
                }
            }

            if (sym != null)
            {
                Convert(ref left, sym.TypeOfOp, options);
                Convert(ref right, sym.TypeOfOp, options);
                return(sym);
            }

            // User-defined operators
            {
                var op = UserDefinedBinaryOperator(kind, ref left, ref right, options);
                if (op != null)
                {
                    return(op);
                }
            }

            // Symbol/string operations
            {
                var op = SymbolAndStringBinaryOperator(kind, ref left, ref right, options);
                if (op != null)
                {
                    return(op);
                }
            }

            // Dynamic with usual
            if (options.HasFlag(BindOptions.AllowDynamic))
            {
                var op = DynamicBinaryOperator(kind, ref left, ref right, options);
                if (op != null)
                {
                    return(op);
                }
            }

            // Emun operations
            {
                var op = EnumBinaryOperator(kind, ref left, ref right, options);
                if (op != null)
                {
                    return(op);
                }
            }

            return(null);
        }