AST.ConditionalExpression.GetExpr C# (CSharp) Метод

GetExpr() публичный Метод

public GetExpr ( ABT env ) : ABT.Expr
env ABT
Результат ABT.Expr
        public override ABT.Expr GetExpr(ABT.Env env) {
            ABT.Expr cond = this.Cond.GetExpr(env);

            if (!cond.Type.IsScalar) {
                throw new InvalidOperationException("Expected a scalar condition in conditional expression.");
            }

            if (cond.Type.IsIntegral) {
                cond = ABT.TypeCast.IntegralPromotion(cond).Item1;
            }

            ABT.Expr true_expr = this.TrueExpr.GetExpr(env);
            ABT.Expr false_expr = this.FalseExpr.GetExpr(env);

            // 1. if both true_expr and false_Expr have arithmetic types:
            //    perform usual arithmetic conversion
            if (true_expr.Type.IsArith && false_expr.Type.IsArith) {
                var r_cast = ABT.TypeCast.UsualArithmeticConversion(true_expr, false_expr);
                true_expr = r_cast.Item1;
                false_expr = r_cast.Item2;
                return new ABT.ConditionalExpr(cond, true_expr, false_expr, true_expr.Type);
            }

            if (true_expr.Type.Kind != false_expr.Type.Kind) {
                throw new InvalidOperationException("Operand types not match in conditional expression.");
            }

            switch (true_expr.Type.Kind) {
                // 2. if both true_expr and false_expr have struct or union Type
                //    make sure they are compatible
                case ABT.ExprTypeKind.STRUCT_OR_UNION:
                    if (!true_expr.Type.EqualType(false_expr.Type)) {
                        throw new InvalidOperationException("Expected compatible types in conditional expression.");
                    }
                    return new ABT.ConditionalExpr(cond, true_expr, false_expr, true_expr.Type);

                // 3. if both true_expr and false_expr have void Type
                //    return void
                case ABT.ExprTypeKind.VOID:
                    return new ABT.ConditionalExpr(cond, true_expr, false_expr, true_expr.Type);

                // 4. if both true_expr and false_expr have pointer Type
                case ABT.ExprTypeKind.POINTER:

                    // if either points to void, convert to void *
                    if (((ABT.PointerType)true_expr.Type).RefType.Kind == ABT.ExprTypeKind.VOID
                        || ((ABT.PointerType)false_expr.Type).RefType.Kind == ABT.ExprTypeKind.VOID) {
                        return new ABT.ConditionalExpr(cond, true_expr, false_expr, new ABT.PointerType(new ABT.VoidType()));
                    }

                    throw new NotImplementedException("More comparisons here.");

                default:
                    throw new InvalidOperationException("Expected compatible types in conditional expression.");
            }
        }
    }