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); }
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); }
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); }