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 }
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); } } }
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); }
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(); } }
internal static CompilationError UnaryOperationError(UnaryExpr expr, UnaryOperatorKind kind, BindOptions options) { return(expr.Error(ErrorCode.UnaryOperationNotFound, UnaryOperatorSymbol.OperatorSymbol(kind), expr.Expr.Datatype)); }
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]); } } }
internal UnaryOperatorSymbolWithType(UnaryOperatorSymbol op, TypeSymbol type) : base(op.Kind, op.OpType) { Type = type; }