Пример #1
0
        Ast.Expression Convert(Ast.Expression expr, TypeSig actualType, TypeSig reqType)
        {
            if (actualType == null || reqType == null || TypeAnalysis.IsSameType(actualType, reqType)) {
                return expr;
            } else if (actualType is ByRefSig && reqType is PtrSig && expr is DirectionExpression) {
                return Convert(
                    new UnaryOperatorExpression(UnaryOperatorType.AddressOf, ((DirectionExpression)expr).Expression.Detach()),
                    new PtrSig(((ByRefSig)actualType).Next),
                    reqType);
            } else if (actualType is PtrSig && reqType is ByRefSig) {
                expr = Convert(expr, actualType, new PtrSig(((ByRefSig)reqType).Next));
                return new DirectionExpression {
                    FieldDirection = FieldDirection.Ref,
                    Expression = new UnaryOperatorExpression(UnaryOperatorType.Dereference, expr)
                };
            } else if (actualType is PtrSig && reqType is PtrSig) {
                if (actualType.FullName != reqType.FullName)
                    return expr.CastTo(AstBuilder.ConvertType(reqType));
                else
                    return expr;
            } else {
                bool actualIsIntegerOrEnum = TypeAnalysis.IsIntegerOrEnum(actualType);
                bool requiredIsIntegerOrEnum = TypeAnalysis.IsIntegerOrEnum(reqType);

                if (reqType.GetElementType() == ElementType.Boolean) {
                    if (actualType.GetElementType() == ElementType.Boolean)
                        return expr;
                    if (actualIsIntegerOrEnum) {
                        return new BinaryOperatorExpression(expr, BinaryOperatorType.InEquality, AstBuilder.MakePrimitive(0, actualType.ToTypeDefOrRef()));
                    } else {
                        return new BinaryOperatorExpression(expr, BinaryOperatorType.InEquality, new NullReferenceExpression());
                    }
                }
                if (actualType.GetElementType() == ElementType.Boolean && requiredIsIntegerOrEnum) {
                    return new ConditionalExpression {
                        Condition = expr,
                        TrueExpression = AstBuilder.MakePrimitive(1, reqType.ToTypeDefOrRef()),
                        FalseExpression = AstBuilder.MakePrimitive(0, reqType.ToTypeDefOrRef())
                    };
                }

                if (expr is PrimitiveExpression && !requiredIsIntegerOrEnum && TypeAnalysis.IsEnum(actualType))
                {
                    return expr.CastTo(AstBuilder.ConvertType(actualType));
                }

                bool actualIsPrimitiveType = actualIsIntegerOrEnum
                    || actualType.GetElementType() == ElementType.R4 || actualType.GetElementType() == ElementType.R8;
                bool requiredIsPrimitiveType = requiredIsIntegerOrEnum
                    || reqType.GetElementType() == ElementType.R4 || reqType.GetElementType() == ElementType.R8;
                if (actualIsPrimitiveType && requiredIsPrimitiveType) {
                    return expr.CastTo(AstBuilder.ConvertType(reqType));
                }
                return expr;
            }
        }
Пример #2
0
 static Ast.DirectionExpression MakeRef(Ast.Expression expr)
 {
     return new DirectionExpression { Expression = expr, FieldDirection = FieldDirection.Ref };
 }