Ejemplo n.º 1
0
        public override ABT.Expr GetExpr(ABT.Env env)
        {
            ABT.Expr expr = this.Expr.GetExpr(env);

            if (!expr.Type.IsIntegral)
            {
                throw new InvalidOperationException("Expected integral Type.");
            }

            expr = ABT.TypeCast.IntegralPromotion(expr).Item1;

            if (expr.IsConstExpr)
            {
                switch (expr.Type.Kind)
                {
                case ABT.ExprTypeKind.LONG:
                    return(new ABT.ConstLong(~((ABT.ConstLong)expr).Value, env));

                case ABT.ExprTypeKind.ULONG:
                    return(new ABT.ConstULong(~((ABT.ConstULong)expr).Value, env));

                default:
                    throw new InvalidOperationException();
                }
            }

            return(new ABT.BitwiseNot(expr));
        }
Ejemplo n.º 2
0
        public static ABT.Expr GetPointerSubtraction(ABT.Expr ptr, ABT.Expr offset)
        {
            if (ptr.Type.Kind != ABT.ExprTypeKind.POINTER)
            {
                throw new InvalidOperationException("Error: expect a pointer");
            }
            if (offset.Type.Kind != ABT.ExprTypeKind.LONG)
            {
                throw new InvalidOperationException("Error: expect an integer");
            }

            if (ptr.IsConstExpr && offset.IsConstExpr)
            {
                Int32 baseAddressValue = (Int32)((ABT.ConstPtr)ptr).Value;
                Int32 scaleFactorValue = ((ABT.PointerType)(ptr.Type)).RefType.SizeOf;
                Int32 offsetValue      = ((ABT.ConstLong)offset).Value;
                return(new ABT.ConstPtr((UInt32)(baseAddressValue - scaleFactorValue * offsetValue), ptr.Type, offset.Env));
            }

            return(ABT.TypeCast.ToPointer(new ABT.Sub(
                                              ABT.TypeCast.FromPointer(ptr, new ABT.LongType(ptr.Type.IsConst, ptr.Type.IsVolatile), ptr.Env),
                                              new ABT.Multiply(
                                                  offset,
                                                  new ABT.ConstLong(((ABT.PointerType)(ptr.Type)).RefType.SizeOf, offset.Env)
                                                  )
                                              ), ptr.Type, offset.Env
                                          ));
        }
Ejemplo n.º 3
0
        public ABT.Expr GetPointerAddition(ABT.Expr ptr, ABT.Expr offset, Boolean order = true)
        {
            if (ptr.Type.Kind != ABT.ExprTypeKind.POINTER)
            {
                throw new InvalidOperationException();
            }
            if (offset.Type.Kind != ABT.ExprTypeKind.LONG)
            {
                throw new InvalidOperationException();
            }

            var env = order ? ptr.Env : offset.Env;

            if (ptr.IsConstExpr && offset.IsConstExpr)
            {
                var   baseValue   = (Int32)((ABT.ConstPtr)ptr).Value;
                Int32 scaleValue  = ((ABT.PointerType)(ptr.Type)).RefType.SizeOf;
                Int32 offsetValue = ((ABT.ConstLong)offset).Value;
                return(new ABT.ConstPtr((UInt32)(baseValue + scaleValue * offsetValue), ptr.Type, env));
            }

            var baseAddress = ABT.TypeCast.FromPointer(ptr, new ABT.LongType(ptr.Type.IsConst, ptr.Type.IsVolatile), ptr.Env);
            var scaleFactor = new ABT.Multiply(
                offset,
                new ABT.ConstLong(((ABT.PointerType)(ptr.Type)).RefType.SizeOf, env)
                );
            var type = new ABT.LongType(offset.Type.IsConst, offset.Type.IsVolatile);
            var add  =
                order
                ? new ABT.Add(baseAddress, scaleFactor)
                : new ABT.Add(scaleFactor, baseAddress);

            return(ABT.TypeCast.ToPointer(add, ptr.Type, env));
        }
Ejemplo n.º 4
0
        public override ABT.Expr GetExpr(ABT.Env env)
        {
            ABT.Expr expr = this.Expr.GetExpr(env);

            if (!expr.Type.IsScalar)
            {
                throw new InvalidOperationException("Expected a scalar.");
            }

            return(new ABT.PostDecrement(expr));
        }
Ejemplo n.º 5
0
        public override Tuple <ABT.Env, ABT.Stmt> GetStmt(ABT.Env env)
        {
            ABT.Expr expr = this.Expr.GetExpr(env);

            Tuple <ABT.Env, ABT.Stmt> r_stmt = this.Stmt.GetStmt(env);

            env = r_stmt.Item1;
            ABT.Stmt stmt = r_stmt.Item2;

            return(new Tuple <ABT.Env, ABT.Stmt>(env, new ABT.SwitchStmt(expr, stmt)));
        }
Ejemplo n.º 6
0
        public override ABT.Expr GetExpr(ABT.Env env)
        {
            ABT.Expr expr = this.Expr.GetExpr(env);

            if (!expr.Type.IsArith)
            {
                throw new InvalidOperationException("Expected arithmetic Type.");
            }

            return(expr);
        }
Ejemplo n.º 7
0
        public override ABT.Expr GetExpr(ABT.Env env)
        {
            ABT.Expr expr = this.Expr.GetExpr(env);
            String   name = this.Member;

            if (expr.Type.Kind != ABT.ExprTypeKind.STRUCT_OR_UNION)
            {
                throw new InvalidOperationException("Must get the attribute from a struct or union.");
            }

            ABT.Utils.StoreEntry entry = (expr.Type as ABT.StructOrUnionType).Attribs.First(_ => _.name == name);
            ABT.ExprType         type  = entry.type;

            return(new ABT.Attribute(expr, name, type));
        }
Ejemplo n.º 8
0
        public override Tuple <ABT.Env, ABT.Stmt> GetStmt(ABT.Env env)
        {
            ABT.Expr cond = this.Cond.GetExpr(env);

            if (!cond.Type.IsScalar)
            {
                throw new InvalidOperationException("Error: expected scalar Type");
            }

            Tuple <ABT.Env, ABT.Stmt> r_stmt = this.Stmt.GetStmt(env);

            env = r_stmt.Item1;
            ABT.Stmt stmt = r_stmt.Item2;

            return(new Tuple <ABT.Env, ABT.Stmt>(env, new ABT.IfStmt(cond, stmt)));
        }
Ejemplo n.º 9
0
        public override ABT.Expr GetExpr(ABT.Env env)
        {
            ABT.Expr expr = this.Expr.GetExpr(env);

            if (expr.Type.Kind != ABT.ExprTypeKind.POINTER)
            {
                throw new InvalidOperationException("Expected a pointer.");
            }

            ABT.ExprType type = ((ABT.PointerType)expr.Type).RefType;
            if (type.Kind == ABT.ExprTypeKind.STRUCT_OR_UNION && !((ABT.StructOrUnionType)type).IsComplete)
            {
                throw new InvalidOperationException("Cannot dereference incomplete Type.");
            }

            return(new ABT.Dereference(expr, type));
        }
Ejemplo n.º 10
0
        public override Tuple <ABT.Env, ABT.Stmt> GetStmt(ABT.Env env)
        {
            Tuple <ABT.Env, ABT.Stmt> r_body = this.Body.GetStmt(env);

            env = r_body.Item1;
            ABT.Stmt body = r_body.Item2;

            ABT.Expr cond = this.Cond.GetExpr(env);
            env = cond.Env;

            if (!cond.Type.IsScalar)
            {
                throw new InvalidOperationException("Error: conditional expression in while Loop must be scalar.");
            }

            return(new Tuple <ABT.Env, ABT.Stmt>(env, new ABT.DoWhileStmt(body, cond)));
        }
Ejemplo n.º 11
0
        public override Tuple <ABT.Env, ABT.Stmt> GetStmt(ABT.Env env)
        {
            ABT.Expr expr = this.Expr.GetExpr(env);
            env = expr.Env;

            expr = ABT.TypeCast.MakeCast(expr, new ABT.LongType());
            if (!expr.IsConstExpr)
            {
                throw new InvalidOperationException("case Expr not const");
            }
            Int32 value = ((ABT.ConstLong)expr).Value;

            Tuple <ABT.Env, ABT.Stmt> r_stmt = this.Stmt.GetStmt(env);

            env = r_stmt.Item1;

            return(new Tuple <ABT.Env, ABT.Stmt>(env, new ABT.CaseStmt(value, r_stmt.Item2)));
        }
Ejemplo n.º 12
0
        public override ABT.Expr GetExpr(ABT.Env env)
        {
            ABT.Expr expr = this.Expr.GetExpr(env);

            if (!expr.Type.IsArith)
            {
                throw new InvalidOperationException("Expected arithmetic Type.");
            }

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

            if (expr.IsConstExpr)
            {
                switch (expr.Type.Kind)
                {
                case ABT.ExprTypeKind.LONG:
                    return(new ABT.ConstLong(-((ABT.ConstLong)expr).Value, env));

                case ABT.ExprTypeKind.ULONG:
                    return(new ABT.ConstLong(-(Int32)((ABT.ConstULong)expr).Value, env));

                case ABT.ExprTypeKind.FLOAT:
                    return(new ABT.ConstFloat(-((ABT.ConstFloat)expr).Value, env));

                case ABT.ExprTypeKind.DOUBLE:
                    return(new ABT.ConstDouble(-((ABT.ConstDouble)expr).Value, env));

                default:
                    throw new InvalidOperationException();
                }
            }

            return(new ABT.Negative(expr));
        }
Ejemplo n.º 13
0
        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.");
            }
        }
Ejemplo n.º 14
0
 public abstract ABT.Expr ConstructExpr(ABT.Expr left, ABT.Expr right, ABT.ExprType type);
Ejemplo n.º 15
0
 public override ABT.Expr ConstructExpr(ABT.Expr left, ABT.Expr right, ABT.ExprType type) =>
 new ABT.RShift(left, right);
Ejemplo n.º 16
0
 public override ABT.Expr ConstructExpr(ABT.Expr left, ABT.Expr right, ABT.ExprType type) =>
 new ABT.LogicalOr(left, right);
Ejemplo n.º 17
0
 public override ABT.Expr ConstructExpr(ABT.Expr left, ABT.Expr right, ABT.ExprType type) =>
 new ABT.Greater(left, right);
Ejemplo n.º 18
0
 public override ABT.Expr ConstructExpr(ABT.Expr left, ABT.Expr right, ABT.ExprType type) =>
 new ABT.NotEqual(left, right);
Ejemplo n.º 19
0
 public override ABT.Expr GetExpr(ABT.Env env)
 {
     ABT.Expr expr = this.Expr.GetExpr(env);
     return(new ABT.Reference(expr));
 }
Ejemplo n.º 20
0
 public override ABT.Expr GetExpr(ABT.Env env)
 {
     ABT.Expr expr = this.Expr.GetExpr(env);
     return(new ABT.ConstULong((UInt32)expr.Type.SizeOf, env));
 }
Ejemplo n.º 21
0
        public override ABT.Expr GetExpr(ABT.Env env)
        {
            // Step 1: get arguments passed into the function.
            // Note that currently the arguments are not casted based on the prototype.
            var args = this.Args.Select(_ => _.GetExpr(env)).ToList();

            // A special case:
            // If we cannot find the function prototype in the environment, make one up.
            // This function returns int.
            // Update the environment to add this function Type.
            if ((this.Func is Variable) && env.Find((this.Func as Variable).Name).IsNone)
            {
                // TODO: get this env used.
                env = env.PushEntry(ABT.Env.EntryKind.TYPEDEF, (this.Func as Variable).Name, ABT.FunctionType.Create(new ABT.LongType(true), args.ConvertAll(_ => Tuple.Create("", _.Type)), false
                                                                                                                     )
                                    );
            }

            // Step 2: get function expression.
            ABT.Expr func = this.Func.GetExpr(env);

            // Step 3: get the function Type.
            ABT.FunctionType func_type;
            switch (func.Type.Kind)
            {
            case ABT.ExprTypeKind.FUNCTION:
                func_type = func.Type as ABT.FunctionType;
                break;

            case ABT.ExprTypeKind.POINTER:
                var ref_t = (func.Type as ABT.PointerType).RefType;
                if (!(ref_t is ABT.FunctionType))
                {
                    throw new InvalidOperationException("Expected a function pointer.");
                }
                func_type = ref_t as ABT.FunctionType;
                break;

            default:
                throw new InvalidOperationException("Expected a function in function call.");
            }


            Int32 num_args_prototype = func_type.Args.Count;
            Int32 num_args_actual    = args.Count;

            // If this function doesn't take varargs, make sure the number of arguments match that in the prototype.
            if (!func_type.HasVarArgs && num_args_actual != num_args_prototype)
            {
                throw new InvalidOperationException("Number of arguments mismatch.");
            }

            // Anyway, you can't call a function with fewer arguments than the prototype.
            if (num_args_actual < num_args_prototype)
            {
                throw new InvalidOperationException("Too few arguments.");
            }

            // Make implicit cast.
            args = args.GetRange(0, num_args_prototype).Zip(func_type.Args,
                                                            (arg, entry) => ABT.TypeCast.MakeCast(arg, entry.type)
                                                            ).Concat(args.GetRange(num_args_prototype, num_args_actual - num_args_prototype)).ToList();

            return(new ABT.FuncCall(func, func_type, args));
        }
Ejemplo n.º 22
0
 public override ABT.Expr GetExpr(ABT.Env env)
 {
     ABT.ExprType type = Semant(this.TypeName.GetExprType, ref env);
     ABT.Expr     expr = this.Expr.GetExpr(env);
     return(ABT.TypeCast.MakeCast(expr, type));
 }
Ejemplo n.º 23
0
 public override ABT.Expr ConstructExpr(ABT.Expr left, ABT.Expr right, ABT.ExprType type) =>
 new ABT.Multiply(left, right);
Ejemplo n.º 24
0
 public override ABT.Expr ConstructExpr(ABT.Expr left, ABT.Expr right, ABT.ExprType type) =>
 new ABT.BitwiseOr(left, right);