private void EmitOptimizedPower(FleeILGenerator ilg, bool emitOverflow, bool unsigned) { Int32LiteralElement right = (Int32LiteralElement)MyRightChild; if (right.Value == 0) { ilg.Emit(OpCodes.Pop); IntegralLiteralElement.EmitLoad(1, ilg); ImplicitConverter.EmitImplicitNumericConvert(typeof(Int32), MyLeftChild.ResultType, ilg); return; } if (right.Value == 1) { return; } // Start at 1 since left operand has already been emited once for (int i = 1; i <= right.Value - 1; i++) { ilg.Emit(OpCodes.Dup); } for (int i = 1; i <= right.Value - 1; i++) { this.EmitMultiply(ilg, emitOverflow, unsigned); } }
/// <summary> /// Emit the load of a constant field. We can't emit a ldsfld/ldfld of a constant so we have to get its value /// and then emit a ldc. /// </summary> /// <param name="fi"></param> /// <param name="ilg"></param> /// <param name="services"></param> private static void EmitLiteral(System.Reflection.FieldInfo fi, FleeILGenerator ilg, IServiceProvider services) { object value = fi.GetValue(null); Type t = value.GetType(); TypeCode code = Type.GetTypeCode(t); LiteralElement elem = default(LiteralElement); switch (code) { case TypeCode.Char: case TypeCode.Byte: case TypeCode.SByte: case TypeCode.Int16: case TypeCode.UInt16: case TypeCode.Int32: elem = new Int32LiteralElement(System.Convert.ToInt32(value)); break; case TypeCode.UInt32: elem = new UInt32LiteralElement((UInt32)value); break; case TypeCode.Int64: elem = new Int64LiteralElement((Int64)value); break; case TypeCode.UInt64: elem = new UInt64LiteralElement((UInt64)value); break; case TypeCode.Double: elem = new DoubleLiteralElement((double)value); break; case TypeCode.Single: elem = new SingleLiteralElement((float)value); break; case TypeCode.Boolean: elem = new BooleanLiteralElement((bool)value); break; case TypeCode.String: elem = new StringLiteralElement((string)value); break; default: elem = null; Debug.Fail("Unsupported constant type"); break; } elem.Emit(ilg, services); }
/// <summary> /// Emit the load of a constant field. /// </summary> /// <remarks> /// We can't emit a ldsfld/ldfld of a constant so we have to get its value and then emit a ldc. /// </remarks> /// <param name="fi"></param> /// <param name="ilg"></param> /// <param name="context"></param> private static void EmitLiteral(FieldInfo fi, YaleIlGenerator ilg, ExpressionContext context) { var value = fi.GetValue(null); var type = value.GetType(); var typeCode = Type.GetTypeCode(type); LiteralElement elem; switch (typeCode) { case TypeCode.Char: case TypeCode.Byte: case TypeCode.SByte: case TypeCode.Int16: case TypeCode.UInt16: case TypeCode.Int32: elem = new Int32LiteralElement(Convert.ToInt32(value)); break; case TypeCode.UInt32: elem = new UInt32LiteralElement((UInt32)value); break; case TypeCode.Int64: elem = new Int64LiteralElement((Int64)value); break; case TypeCode.UInt64: elem = new UInt64LiteralElement((UInt64)value); break; case TypeCode.Double: elem = new DoubleLiteralElement((double)value); break; case TypeCode.Single: elem = new SingleLiteralElement((float)value); break; case TypeCode.Boolean: elem = new BooleanLiteralElement((bool)value); break; case TypeCode.String: elem = new StringLiteralElement((string)value); break; default: elem = null; Debug.Fail("Unsupported constant type"); break; } elem.Emit(ilg, context); }
private static void EmitStringEquality(FleeILGenerator ilg, LogicalCompareOperation op, IServiceProvider services) { // Get the StringComparison from the options ExpressionOptions options = (ExpressionOptions)services.GetService(typeof(ExpressionOptions)); Int32LiteralElement ic = new Int32LiteralElement((int)options.StringComparison); ic.Emit(ilg, services); // and emit the method call System.Reflection.MethodInfo mi = typeof(string).GetMethod("Equals", new Type[] { typeof(string), typeof(string), typeof(StringComparison) }, null); ilg.Emit(OpCodes.Call, mi); if (op == LogicalCompareOperation.NotEqual) { ilg.Emit(OpCodes.Ldc_I4_0); ilg.Emit(OpCodes.Ceq); } }
private static void EmitStringEquality(YaleIlGenerator ilg, LogicalCompareOperation op, ExpressionContext context) { // Get the StringComparison from the options var options = context.BuilderOptions; var int32LiteralElement = new Int32LiteralElement((int)options.StringComparison); int32LiteralElement.Emit(ilg, context); // and emit the method call var methodInfo = typeof(string).GetMethod("Equals", new[] { typeof(string), typeof(string), typeof(StringComparison) }, null); ilg.Emit(OpCodes.Call, methodInfo); if (op == LogicalCompareOperation.NotEqual) { ilg.Emit(OpCodes.Ldc_I4_0); ilg.Emit(OpCodes.Ceq); } }
/// <summary> /// Attempt to find the first type of integer that a number can fit into /// </summary> /// <param name="image"></param> /// <param name="isHex"></param> /// <param name="negated"></param> /// <param name="services"></param> /// <returns></returns> public static LiteralElement Create(string image, bool isHex, bool negated, IServiceProvider services) { StringComparison comparison = StringComparison.OrdinalIgnoreCase; if (isHex == false) { // Create a real element if required LiteralElement realElement = RealLiteralElement.CreateFromInteger(image, services); if ((realElement != null)) { return(realElement); } } bool hasUSuffix = image.EndsWith("u", comparison) & !image.EndsWith("lu", comparison); bool hasLSuffix = image.EndsWith("l", comparison) & !image.EndsWith("ul", comparison); bool hasUlSuffix = image.EndsWith("ul", comparison) | image.EndsWith("lu", comparison); bool hasSuffix = hasUSuffix | hasLSuffix | hasUlSuffix; LiteralElement constant = default(LiteralElement); System.Globalization.NumberStyles numStyles = NumberStyles.Integer; if (isHex == true) { numStyles = NumberStyles.AllowHexSpecifier; image = image.Remove(0, 2); } if (hasSuffix == false) { // If the literal has no suffix, it has the first of these types in which its value can be represented: int, uint, long, ulong. constant = Int32LiteralElement.TryCreate(image, isHex, negated); if ((constant != null)) { return(constant); } constant = UInt32LiteralElement.TryCreate(image, numStyles); if ((constant != null)) { return(constant); } constant = Int64LiteralElement.TryCreate(image, isHex, negated); if ((constant != null)) { return(constant); } return(new UInt64LiteralElement(image, numStyles)); } else if (hasUSuffix == true) { image = image.Remove(image.Length - 1); // If the literal is suffixed by U or u, it has the first of these types in which its value can be represented: uint, ulong. constant = UInt32LiteralElement.TryCreate(image, numStyles); if ((constant != null)) { return(constant); } else { return(new UInt64LiteralElement(image, numStyles)); } } else if (hasLSuffix == true) { // If the literal is suffixed by L or l, it has the first of these types in which its value can be represented: long, ulong. image = image.Remove(image.Length - 1); constant = Int64LiteralElement.TryCreate(image, isHex, negated); if ((constant != null)) { return(constant); } else { return(new UInt64LiteralElement(image, numStyles)); } } else { // If the literal is suffixed by UL, Ul, uL, ul, LU, Lu, lU, or lu, it is of type ulong. Debug.Assert(hasUlSuffix == true, "expecting ul suffix"); image = image.Remove(image.Length - 2); return(new UInt64LiteralElement(image, numStyles)); } }
/// <summary> /// Attempt to find the first type of integer that a number can fit into /// </summary> /// <param name="image"></param> /// <param name="isHex"></param> /// <param name="negated"></param> /// <param name="options"></param> /// <returns></returns> public static LiteralElement Create(string image, bool isHex, bool negated, ExpressionBuilderOptions options) { const StringComparison comparison = StringComparison.OrdinalIgnoreCase; if (isHex == false) { // Create a real element if required var realElement = RealLiteralElement.CreateFromInteger(image, options); if (realElement != null) { return(realElement); } } var hasUSuffix = image.EndsWith("u", comparison) & !image.EndsWith("lu", comparison); var hasLSuffix = image.EndsWith("l", comparison) & !image.EndsWith("ul", comparison); var hasUlSuffix = image.EndsWith("ul", comparison) | image.EndsWith("lu", comparison); var hasSuffix = hasUSuffix | hasLSuffix | hasUlSuffix; LiteralElement constant; var numStyles = NumberStyles.Integer; if (isHex) { numStyles = NumberStyles.AllowHexSpecifier; image = image.Remove(0, 2); } if (hasSuffix == false) { // If the literal has no suffix, it has the first of these types in which its value can be represented: int, uint, long, ulong. constant = Int32LiteralElement.TryCreate(image, isHex, negated); if (constant != null) { return(constant); } constant = UInt32LiteralElement.TryCreate(image, numStyles); if (constant != null) { return(constant); } constant = Int64LiteralElement.TryCreate(image, isHex, negated); if (constant != null) { return(constant); } return(new UInt64LiteralElement(image, numStyles)); } if (hasUSuffix) { image = image.Remove(image.Length - 1); // If the literal is suffixed by U or u, it has the first of these types in which its value can be represented: uint, ulong. constant = UInt32LiteralElement.TryCreate(image, numStyles); return(constant ?? new UInt64LiteralElement(image, numStyles)); } if (hasLSuffix) { // If the literal is suffixed by L or l, it has the first of these types in which its value can be represented: long, ulong. image = image.Remove(image.Length - 1); constant = Int64LiteralElement.TryCreate(image, isHex, negated); return(constant ?? new UInt64LiteralElement(image, numStyles)); } // If the literal is suffixed by UL, Ul, uL, ul, LU, Lu, lU, or lu, it is of type ulong. Debug.Assert(true, "expecting ul suffix"); image = image.Remove(image.Length - 2); return(new UInt64LiteralElement(image, numStyles)); }