Пример #1
0
        protected virtual EXPR GenerateUserDefinedComparisonOperator(EXPRBINOP expr)
        {
            Debug.Assert(expr != null);
            Debug.Assert(alwaysRewrite || currentAnonMeth != null);
            PREDEFMETH pdm;

            switch (expr.kind)
            {
                case ExpressionKind.EK_STRINGEQ: pdm = PREDEFMETH.PM_EXPRESSION_EQUAL_USER_DEFINED; break;
                case ExpressionKind.EK_STRINGNE: pdm = PREDEFMETH.PM_EXPRESSION_NOTEQUAL_USER_DEFINED; break;
                case ExpressionKind.EK_DELEGATEEQ: pdm = PREDEFMETH.PM_EXPRESSION_EQUAL_USER_DEFINED; break;
                case ExpressionKind.EK_DELEGATENE: pdm = PREDEFMETH.PM_EXPRESSION_NOTEQUAL_USER_DEFINED; break;
                case ExpressionKind.EK_EQ: pdm = PREDEFMETH.PM_EXPRESSION_EQUAL_USER_DEFINED; break;
                case ExpressionKind.EK_NE: pdm = PREDEFMETH.PM_EXPRESSION_NOTEQUAL_USER_DEFINED; break;
                case ExpressionKind.EK_LE: pdm = PREDEFMETH.PM_EXPRESSION_LESSTHANOREQUAL_USER_DEFINED; break;
                case ExpressionKind.EK_LT: pdm = PREDEFMETH.PM_EXPRESSION_LESSTHAN_USER_DEFINED; break;
                case ExpressionKind.EK_GE: pdm = PREDEFMETH.PM_EXPRESSION_GREATERTHANOREQUAL_USER_DEFINED; break;
                case ExpressionKind.EK_GT: pdm = PREDEFMETH.PM_EXPRESSION_GREATERTHAN_USER_DEFINED; break;
                default:
                    throw Error.InternalCompilerError();
            }
            EXPR p1 = expr.GetOptionalLeftChild();
            EXPR p2 = expr.GetOptionalRightChild();
            if (expr.GetOptionalUserDefinedCall() != null)
            {
                EXPRCALL udcall = expr.GetOptionalUserDefinedCall().asCALL();
                EXPRLIST args = udcall.GetOptionalArguments().asLIST();
                Debug.Assert(args.GetOptionalNextListNode().kind != ExpressionKind.EK_LIST);

                p1 = args.GetOptionalElement();
                p2 = args.GetOptionalNextListNode();
            }
            p1 = Visit(p1);
            p2 = Visit(p2);
            FixLiftedUserDefinedBinaryOperators(expr, ref p1, ref p2);
            EXPR lift = GetExprFactory().CreateBoolConstant(false); // We never lift to null in C#.
            EXPR methodInfo = GetExprFactory().CreateMethodInfo(expr.GetUserDefinedCallMethod());
            return GenerateCall(pdm, p1, p2, lift, methodInfo);
        }
Пример #2
0
        protected virtual EXPR GenerateUserDefinedBinaryOperator(EXPRBINOP expr)
        {
            Debug.Assert(expr != null);
            Debug.Assert(alwaysRewrite || currentAnonMeth != null);
            PREDEFMETH pdm;

            switch (expr.kind)
            {
                case ExpressionKind.EK_LOGOR: pdm = PREDEFMETH.PM_EXPRESSION_ORELSE_USER_DEFINED; break;
                case ExpressionKind.EK_LOGAND: pdm = PREDEFMETH.PM_EXPRESSION_ANDALSO_USER_DEFINED; break;
                case ExpressionKind.EK_LSHIFT: pdm = PREDEFMETH.PM_EXPRESSION_LEFTSHIFT_USER_DEFINED; break;
                case ExpressionKind.EK_RSHIFT: pdm = PREDEFMETH.PM_EXPRESSION_RIGHTSHIFT_USER_DEFINED; break;
                case ExpressionKind.EK_BITXOR: pdm = PREDEFMETH.PM_EXPRESSION_EXCLUSIVEOR_USER_DEFINED; break;
                case ExpressionKind.EK_BITOR: pdm = PREDEFMETH.PM_EXPRESSION_OR_USER_DEFINED; break;
                case ExpressionKind.EK_BITAND: pdm = PREDEFMETH.PM_EXPRESSION_AND_USER_DEFINED; break;
                case ExpressionKind.EK_MOD: pdm = PREDEFMETH.PM_EXPRESSION_MODULO_USER_DEFINED; break;
                case ExpressionKind.EK_DIV: pdm = PREDEFMETH.PM_EXPRESSION_DIVIDE_USER_DEFINED; break;
                case ExpressionKind.EK_STRINGEQ:
                case ExpressionKind.EK_STRINGNE:
                case ExpressionKind.EK_DELEGATEEQ:
                case ExpressionKind.EK_DELEGATENE:
                case ExpressionKind.EK_EQ:
                case ExpressionKind.EK_NE:
                case ExpressionKind.EK_GE:
                case ExpressionKind.EK_GT:
                case ExpressionKind.EK_LE:
                case ExpressionKind.EK_LT:
                    return GenerateUserDefinedComparisonOperator(expr);
                case ExpressionKind.EK_DELEGATESUB:
                case ExpressionKind.EK_SUB:
                    pdm = expr.isChecked() ? PREDEFMETH.PM_EXPRESSION_SUBTRACTCHECKED_USER_DEFINED : PREDEFMETH.PM_EXPRESSION_SUBTRACT_USER_DEFINED;
                    break;
                case ExpressionKind.EK_DELEGATEADD:
                case ExpressionKind.EK_ADD:
                    pdm = expr.isChecked() ? PREDEFMETH.PM_EXPRESSION_ADDCHECKED_USER_DEFINED : PREDEFMETH.PM_EXPRESSION_ADD_USER_DEFINED;
                    break;
                case ExpressionKind.EK_MUL:
                    pdm = expr.isChecked() ? PREDEFMETH.PM_EXPRESSION_MULTIPLYCHECKED_USER_DEFINED : PREDEFMETH.PM_EXPRESSION_MULTIPLY_USER_DEFINED;
                    break;
                default:
                    throw Error.InternalCompilerError();
            }
            EXPR p1 = expr.GetOptionalLeftChild();
            EXPR p2 = expr.GetOptionalRightChild();
            EXPR udcall = expr.GetOptionalUserDefinedCall();
            if (udcall != null)
            {
                Debug.Assert(udcall.kind == ExpressionKind.EK_CALL || udcall.kind == ExpressionKind.EK_USERLOGOP);
                if (udcall.kind == ExpressionKind.EK_CALL)
                {
                    EXPRLIST args = udcall.asCALL().GetOptionalArguments().asLIST();
                    Debug.Assert(args.GetOptionalNextListNode().kind != ExpressionKind.EK_LIST);
                    p1 = args.GetOptionalElement();
                    p2 = args.GetOptionalNextListNode();
                }
                else
                {
                    EXPRLIST args = udcall.asUSERLOGOP().OperatorCall.GetOptionalArguments().asLIST();
                    Debug.Assert(args.GetOptionalNextListNode().kind != ExpressionKind.EK_LIST);
                    p1 = args.GetOptionalElement().asWRAP().GetOptionalExpression();
                    p2 = args.GetOptionalNextListNode();
                }
            }
            p1 = Visit(p1);
            p2 = Visit(p2);
            FixLiftedUserDefinedBinaryOperators(expr, ref p1, ref p2);
            EXPR methodInfo = GetExprFactory().CreateMethodInfo(expr.GetUserDefinedCallMethod());
            EXPR call = GenerateCall(pdm, p1, p2, methodInfo);
            // Delegate add/subtract generates a call to Combine/Remove, which returns System.Delegate,
            // not the operand delegate CType.  We must cast to the delegate CType.
            if (expr.kind == ExpressionKind.EK_DELEGATESUB || expr.kind == ExpressionKind.EK_DELEGATEADD)
            {
                EXPR pTypeOf = CreateTypeOf(expr.type);
                return GenerateCall(PREDEFMETH.PM_EXPRESSION_CONVERT, call, pTypeOf);
            }
            return call;
        }