Пример #1
0
        public override ABT.Expr GetExpr(ABT.Env env)
        {
            var left  = SemantExpr(this.Left, ref env);
            var right = SemantExpr(this.Right, ref env);

            if (left.Type is ABT.ArrayType)
            {
                left = ABT.TypeCast.MakeCast(left, new ABT.PointerType((left.Type as ABT.ArrayType).ElemType, left.Type.IsConst, left.Type.IsVolatile));
            }

            if (right.Type is ABT.ArrayType)
            {
                right = ABT.TypeCast.MakeCast(right, new ABT.PointerType((right.Type as ABT.ArrayType).ElemType, right.Type.IsConst, right.Type.IsVolatile));
            }

            var isConst    = left.Type.IsConst || right.Type.IsConst;
            var isVolatile = left.Type.IsVolatile || right.Type.IsVolatile;

            if (left.Type.Kind == ABT.ExprTypeKind.POINTER)
            {
                // 1. ptr - ptr
                if (right.Type.Kind == ABT.ExprTypeKind.POINTER)
                {
                    ABT.PointerType leftType  = (ABT.PointerType)(left.Type);
                    ABT.PointerType rightType = (ABT.PointerType)(right.Type);
                    if (!leftType.RefType.EqualType(rightType.RefType))
                    {
                        throw new InvalidOperationException("The 2 pointers don't match.");
                    }

                    Int32 scale = leftType.RefType.SizeOf;

                    if (left.IsConstExpr && right.IsConstExpr)
                    {
                        return(new ABT.ConstLong((Int32)(((ABT.ConstPtr)left).Value - ((ABT.ConstPtr)right).Value) / scale, env));
                    }

                    return(new ABT.Divide(
                               new ABT.Sub(
                                   ABT.TypeCast.MakeCast(left, new ABT.LongType(isConst, isVolatile)),
                                   ABT.TypeCast.MakeCast(right, new ABT.LongType(isConst, isVolatile))
                                   ),
                               new ABT.ConstLong(scale, env)
                               ));
                }

                // 2. ptr - integral
                if (!right.Type.IsIntegral)
                {
                    throw new InvalidOperationException("Expected an integral.");
                }
                right = ABT.TypeCast.MakeCast(right, new ABT.LongType(right.Type.IsConst, right.Type.IsVolatile));
                return(GetPointerSubtraction(left, right));
            }

            // 3. arith - arith
            return(base.GetExpr(env));
        }
Пример #2
0
 public static void TestPointer() {
     var type = new ABT.PointerType(
         new ABT.LongType(isConst: true),
         isConst: true,
         isVolatile: true
     );
     Assert.AreEqual("const long *const volatile a", type.Decl("a"));
     Assert.AreEqual("const long *const volatile", type.Decl());
 }
Пример #3
0
        public static void TestPointer()
        {
            var type = new ABT.PointerType(
                new ABT.LongType(isConst: true),
                isConst: true,
                isVolatile: true
                );

            Assert.AreEqual("const long *const volatile a", type.Decl("a"));
            Assert.AreEqual("const long *const volatile", type.Decl());
        }
Пример #4
0
        public static void TestArrayPointer()
        {
            var arrPtr = new ABT.PointerType(
                new ABT.ArrayType(
                    new ABT.LongType(),
                    3
                    )
                );

            Assert.AreEqual("long (*a)[3]", arrPtr.Decl("a"));
            Assert.AreEqual("long (*)[3]", arrPtr.Decl());
        }
Пример #5
0
        public static void TestFunctionPointer()
        {
            var funcPtr = new ABT.PointerType(
                ABT.FunctionType.Create(
                    ABT.StructOrUnionType.CreateIncompleteStruct("my_struct", false, false),
                    ImmutableList.Create(
                        Tuple.Create(Option <String> .None, new ABT.LongType() as ABT.ExprType)
                        ),
                    false
                    )
                );

            Assert.AreEqual("struct my_struct (*a)(long)", funcPtr.Decl("a"));
            Assert.AreEqual("struct my_struct (*)(long)", funcPtr.Decl());
        }
Пример #6
0
 public static void TestArrayPointer() {
     var arrPtr = new ABT.PointerType(
         new ABT.ArrayType(
             new ABT.LongType(),
             3
         )
     );
     Assert.AreEqual("long (*a)[3]", arrPtr.Decl("a"));
     Assert.AreEqual("long (*)[3]", arrPtr.Decl());
 }
Пример #7
0
 public static void TestFunctionPointer() {
     var funcPtr = new ABT.PointerType(
         ABT.FunctionType.Create(
             ABT.StructOrUnionType.CreateIncompleteStruct("my_struct", false, false),
             ImmutableList.Create(
                 Tuple.Create(Option<String>.None, new ABT.LongType() as ABT.ExprType)
             ),
             false
         )
     );
     Assert.AreEqual("struct my_struct (*a)(long)", funcPtr.Decl("a"));
     Assert.AreEqual("struct my_struct (*)(long)", funcPtr.Decl());
 }