Beispiel #1
0
        static UnaryOperatorSymbol()
        {
            var ops     = (UnaryOperatorKind[])Enum.GetValues(typeof(UnaryOperatorKind));
            var opTypes = (OperandType[])Enum.GetValues(typeof(OperandType));

            simpleOp = new UnaryOperatorSymbol[ops.Length, opTypes.Length];

            foreach (var o in ops)
            {
                foreach (var c in opTypes)
                {
                    if (o != UnaryOperatorKind.Error && c != OperandType.Error)
                    {
                        simpleOp[(int)o, (int)c] = new UnaryOperatorSymbol(o, c);
                    }
                }
            }

#if DEBUG
            /*
             * foreach (var o in ops)
             * {
             *  if (o != UnaryOperatorKind.Error)
             *      Debug.Assert(OperatorName(o) != null);
             * }
             */
#endif
        }
Beispiel #2
0
 static void ApplyUnaryOperator(ref Expr expr, UnaryOperatorSymbol op)
 {
     if (op is UnaryOperatorSymbolWithMethod)
     {
         var mop        = (UnaryOperatorSymbolWithMethod)op;
         var parameters = mop.Method.Method.GetParameters();
         var conv       = mop.Conv;
         if (conv != null && conv.Kind != ConversionKind.Identity)
         {
             Convert(ref expr, FindType(parameters[0].ParameterType), conv);
         }
     }
 }
Beispiel #3
0
        internal static UnaryOperatorSymbol UserDefinedUnaryOperator(UnaryOperatorKind kind, ref Expr expr, BindOptions options)
        {
            var name = UnaryOperatorSymbol.OperatorName(kind);

            if (name != null)
            {
                MethodSymbol     mop  = null;
                ConversionSymbol conv = null;
                ResolveUserDefinedUnaryOperator(expr, expr.Datatype.Lookup(name), ref mop, ref conv, options);
                if (mop != null)
                {
                    var op = UnaryOperatorSymbol.Create(kind, mop, conv);
                    ApplyUnaryOperator(ref expr, op);
                    return(op);
                }
            }
            return(null);
        }
Beispiel #4
0
        internal static void EmitUnaryOperator(ILGenerator ilg, UnaryOperatorSymbol op, TypeSymbol type)
        {
            switch (op.Kind)
            {
            case UnaryOperatorKind.Increment:
                EmitConstant_1(ilg, type.NativeType);
                ilg.Emit(OpCodes.Add);
                break;

            case UnaryOperatorKind.Decrement:
                EmitConstant_1(ilg, type.NativeType);
                ilg.Emit(OpCodes.Sub);
                break;

            case UnaryOperatorKind.UnaryPlus:
                break;

            case UnaryOperatorKind.UnaryMinus:
                ilg.Emit(OpCodes.Neg);
                break;

            case UnaryOperatorKind.LogicalNegation:
                ilg.Emit(OpCodes.Ldc_I4_0);
                ilg.Emit(OpCodes.Ceq);
                break;

            case UnaryOperatorKind.BitwiseComplement:
                ilg.Emit(OpCodes.Not);
                break;

            case UnaryOperatorKind.True:
                break;

            case UnaryOperatorKind.False:
                break;

            default:
                throw new InternalError();
            }
        }
Beispiel #5
0
 internal static CompilationError UnaryOperationError(UnaryExpr expr, UnaryOperatorKind kind, BindOptions options)
 {
     return(expr.Error(ErrorCode.UnaryOperationNotFound, UnaryOperatorSymbol.OperatorSymbol(kind), expr.Expr.Datatype));
 }
Beispiel #6
0
        static UnaryOperatorEasyOut()
        {
            const OperandType ERR = OperandType.Error;
            const OperandType BOL = OperandType.Bool;
            const OperandType CHR = OperandType.Char;
            const OperandType I08 = OperandType.SByte;
            const OperandType U08 = OperandType.Byte;
            const OperandType I16 = OperandType.Short;
            const OperandType U16 = OperandType.UShort;
            const OperandType I32 = OperandType.Int;
            const OperandType U32 = OperandType.UInt;
            const OperandType I64 = OperandType.Long;
            const OperandType U64 = OperandType.ULong;
            const OperandType R32 = OperandType.Float;
            const OperandType R64 = OperandType.Double;
            const OperandType DEC = OperandType.Decimal;

            OperandType[] increment =
                //bool chr  i08  i16  i32  i64  u08  u16  u32  u64  r32  r64  dec
            { ERR, CHR, I08, I16, I32, I64, U08, U16, U32, U64, R32, R64, DEC };

            OperandType[] plus =
                //bool chr  i08  i16  i32  i64  u08  u16  u32  u64  r32  r64  dec
            { ERR, I32, I32, I32, I32, I64, I32, I32, U32, U64, R32, R64, DEC };

            OperandType[] minus =
                //bool chr  i08  i16  i32  i64  u08  u16  u32  u64  r32  r64  dec
            { ERR, I32, I32, I32, I32, I64, I32, I32, I64, ERR, R32, R64, DEC };

            OperandType[] logicalNegation =
                //bool chr  i08  i16  i32  i64  u08  u16  u32  u64  r32  r64  dec
            { BOL, ERR, ERR, ERR, ERR, ERR, ERR, ERR, ERR, ERR, ERR, ERR, ERR };

            OperandType[] bitwiseComplement =
                //bool chr  i08  i16  i32  i64  u08  u16  u32  u64  r32  r64  dec
            { ERR, I32, I32, I32, I32, I64, I32, I32, U32, U64, ERR, ERR, ERR };

            var ops = (UnaryOperatorKind[])Enum.GetValues(typeof(UnaryOperatorKind));

            s_unOp = new UnaryOperatorSymbol[ops.Length][];
            s_unOp[(int)UnaryOperatorKind.Error] = new UnaryOperatorSymbol[28];

            for (int i = 0; i < 28; i++)
            {
                s_unOp[(int)UnaryOperatorKind.Error][i] = UnaryOperatorSymbol.Create(UnaryOperatorKind.Error, OperandType.Error);
            }

            for (int i = ((int)UnaryOperatorKind.Error) + 1; i < ops.Length; i++)
            {
                s_unOp[i] = s_unOp[(int)UnaryOperatorKind.Error];
            }

            Func <UnaryOperatorKind, OperandType[], UnaryOperatorSymbol[]> expandTable = (k, x) =>
            {
                var res = new UnaryOperatorSymbol[28];
                for (int i = 0; i < 13; i++)
                {
                    var t  = x[i];
                    var nt = OperandTypeHelper.IsNullable(t + OperandTypeHelper.NullableDelta) ? t + OperandTypeHelper.NullableDelta : t;
                    res[i + 2]      = UnaryOperatorSymbol.Create(k, t);
                    res[i + 2 + 13] = UnaryOperatorSymbol.Create(k, nt);
                }
                return(res);
            };

            var tables = new[] { increment, plus, minus, logicalNegation, bitwiseComplement };

            Func <UnaryOperatorKind, int> tableIndex = k =>
            {
                if (k == UnaryOperatorKind.Increment || k == UnaryOperatorKind.Decrement)
                {
                    return(0);
                }
                if (k == UnaryOperatorKind.UnaryPlus)
                {
                    return(1);
                }
                if (k == UnaryOperatorKind.UnaryMinus)
                {
                    return(2);
                }
                if (k == UnaryOperatorKind.LogicalNegation)
                {
                    return(3);
                }
                if (k == UnaryOperatorKind.BitwiseComplement)
                {
                    return(4);
                }
                return(-1);
            };

            for (int i = ((int)UnaryOperatorKind.Error) + 1; i < ops.Length; i++)
            {
                var k  = (UnaryOperatorKind)i;
                var ti = tableIndex(k);
                if (ti >= 0)
                {
                    s_unOp[i] = expandTable(k, tables[ti]);
                }
            }
        }
Beispiel #7
0
 internal UnaryOperatorSymbolWithType(UnaryOperatorSymbol op, TypeSymbol type) : base(op.Kind, op.OpType)
 {
     Type = type;
 }