Flee
This commit is contained in:
118
ExpressionElements/Base/Literals/Integral.cs
Normal file
118
ExpressionElements/Base/Literals/Integral.cs
Normal file
@@ -0,0 +1,118 @@
|
||||
using System.Diagnostics;
|
||||
using System.Globalization;
|
||||
using Flee.ExpressionElements.Literals.Integral;
|
||||
|
||||
|
||||
namespace Flee.ExpressionElements.Base.Literals
|
||||
{
|
||||
internal abstract class IntegralLiteralElement : LiteralElement
|
||||
{
|
||||
protected IntegralLiteralElement()
|
||||
{
|
||||
}
|
||||
|
||||
/// <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);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
107
ExpressionElements/Base/Literals/LiteralElement.cs
Normal file
107
ExpressionElements/Base/Literals/LiteralElement.cs
Normal file
@@ -0,0 +1,107 @@
|
||||
using System.Diagnostics;
|
||||
using System.Reflection.Emit;
|
||||
using Flee.InternalTypes;
|
||||
using Flee.PublicTypes;
|
||||
using Flee.Resources;
|
||||
|
||||
|
||||
namespace Flee.ExpressionElements.Base.Literals
|
||||
{
|
||||
internal abstract class LiteralElement : ExpressionElement
|
||||
{
|
||||
protected void OnParseOverflow(string image)
|
||||
{
|
||||
base.ThrowCompileException(CompileErrorResourceKeys.ValueNotRepresentableInType, CompileExceptionReason.ConstantOverflow, image, this.ResultType.Name);
|
||||
}
|
||||
|
||||
public static void EmitLoad(Int32 value, FleeILGenerator ilg)
|
||||
{
|
||||
if (value >= -1 & value <= 8)
|
||||
{
|
||||
EmitSuperShort(value, ilg);
|
||||
}
|
||||
else if (value >= sbyte.MinValue & value <= sbyte.MaxValue)
|
||||
{
|
||||
ilg.Emit(OpCodes.Ldc_I4_S, Convert.ToSByte(value));
|
||||
}
|
||||
else
|
||||
{
|
||||
ilg.Emit(OpCodes.Ldc_I4, value);
|
||||
}
|
||||
}
|
||||
|
||||
protected static void EmitLoad(Int64 value, FleeILGenerator ilg)
|
||||
{
|
||||
if (value >= Int32.MinValue & value <= Int32.MaxValue)
|
||||
{
|
||||
EmitLoad(Convert.ToInt32(value), ilg);
|
||||
ilg.Emit(OpCodes.Conv_I8);
|
||||
}
|
||||
else if (value >= 0 & value <= UInt32.MaxValue)
|
||||
{
|
||||
ilg.Emit(OpCodes.Ldc_I4, unchecked((int)Convert.ToUInt32(value)));
|
||||
ilg.Emit(OpCodes.Conv_U8);
|
||||
}
|
||||
else
|
||||
{
|
||||
ilg.Emit(OpCodes.Ldc_I8, value);
|
||||
}
|
||||
}
|
||||
|
||||
protected static void EmitLoad(bool value, FleeILGenerator ilg)
|
||||
{
|
||||
if (value == true)
|
||||
{
|
||||
ilg.Emit(OpCodes.Ldc_I4_1);
|
||||
}
|
||||
else
|
||||
{
|
||||
ilg.Emit(OpCodes.Ldc_I4_0);
|
||||
}
|
||||
}
|
||||
|
||||
private static void EmitSuperShort(Int32 value, FleeILGenerator ilg)
|
||||
{
|
||||
OpCode ldcOpcode = default(OpCode);
|
||||
|
||||
switch (value)
|
||||
{
|
||||
case 0:
|
||||
ldcOpcode = OpCodes.Ldc_I4_0;
|
||||
break;
|
||||
case 1:
|
||||
ldcOpcode = OpCodes.Ldc_I4_1;
|
||||
break;
|
||||
case 2:
|
||||
ldcOpcode = OpCodes.Ldc_I4_2;
|
||||
break;
|
||||
case 3:
|
||||
ldcOpcode = OpCodes.Ldc_I4_3;
|
||||
break;
|
||||
case 4:
|
||||
ldcOpcode = OpCodes.Ldc_I4_4;
|
||||
break;
|
||||
case 5:
|
||||
ldcOpcode = OpCodes.Ldc_I4_5;
|
||||
break;
|
||||
case 6:
|
||||
ldcOpcode = OpCodes.Ldc_I4_6;
|
||||
break;
|
||||
case 7:
|
||||
ldcOpcode = OpCodes.Ldc_I4_7;
|
||||
break;
|
||||
case 8:
|
||||
ldcOpcode = OpCodes.Ldc_I4_8;
|
||||
break;
|
||||
case -1:
|
||||
ldcOpcode = OpCodes.Ldc_I4_M1;
|
||||
break;
|
||||
default:
|
||||
Debug.Assert(false, "value out of range");
|
||||
break;
|
||||
}
|
||||
|
||||
ilg.Emit(ldcOpcode);
|
||||
}
|
||||
}
|
||||
}
|
130
ExpressionElements/Base/Literals/Real.cs
Normal file
130
ExpressionElements/Base/Literals/Real.cs
Normal file
@@ -0,0 +1,130 @@
|
||||
using System.Diagnostics;
|
||||
using Flee.ExpressionElements.Literals.Real;
|
||||
using Flee.PublicTypes;
|
||||
|
||||
namespace Flee.ExpressionElements.Base.Literals
|
||||
{
|
||||
internal abstract class RealLiteralElement : LiteralElement
|
||||
{
|
||||
protected RealLiteralElement()
|
||||
{
|
||||
}
|
||||
|
||||
public static LiteralElement CreateFromInteger(string image, IServiceProvider services)
|
||||
{
|
||||
LiteralElement element = default(LiteralElement);
|
||||
|
||||
element = CreateSingle(image, services);
|
||||
|
||||
if ((element != null))
|
||||
{
|
||||
return element;
|
||||
}
|
||||
|
||||
element = CreateDecimal(image, services);
|
||||
|
||||
if ((element != null))
|
||||
{
|
||||
return element;
|
||||
}
|
||||
|
||||
ExpressionOptions options = (ExpressionOptions)services.GetService(typeof(ExpressionOptions));
|
||||
|
||||
// Convert to a double if option is set
|
||||
if (options.IntegersAsDoubles == true)
|
||||
{
|
||||
return DoubleLiteralElement.Parse(image, services);
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
public static LiteralElement Create(string image, IServiceProvider services)
|
||||
{
|
||||
LiteralElement element = default(LiteralElement);
|
||||
|
||||
element = CreateSingle(image, services);
|
||||
|
||||
if ((element != null))
|
||||
{
|
||||
return element;
|
||||
}
|
||||
|
||||
element = CreateDecimal(image, services);
|
||||
|
||||
if ((element != null))
|
||||
{
|
||||
return element;
|
||||
}
|
||||
|
||||
element = CreateDouble(image, services);
|
||||
|
||||
if ((element != null))
|
||||
{
|
||||
return element;
|
||||
}
|
||||
|
||||
element = CreateImplicitReal(image, services);
|
||||
|
||||
return element;
|
||||
}
|
||||
|
||||
private static LiteralElement CreateImplicitReal(string image, IServiceProvider services)
|
||||
{
|
||||
ExpressionOptions options = (ExpressionOptions)services.GetService(typeof(ExpressionOptions));
|
||||
RealLiteralDataType realType = options.RealLiteralDataType;
|
||||
|
||||
switch (realType)
|
||||
{
|
||||
case RealLiteralDataType.Double:
|
||||
return DoubleLiteralElement.Parse(image, services);
|
||||
case RealLiteralDataType.Single:
|
||||
return SingleLiteralElement.Parse(image, services);
|
||||
case RealLiteralDataType.Decimal:
|
||||
return DecimalLiteralElement.Parse(image, services);
|
||||
default:
|
||||
Debug.Fail("Unknown value");
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
private static DoubleLiteralElement CreateDouble(string image, IServiceProvider services)
|
||||
{
|
||||
if (image.EndsWith("d", StringComparison.OrdinalIgnoreCase) == true)
|
||||
{
|
||||
image = image.Remove(image.Length - 1);
|
||||
return DoubleLiteralElement.Parse(image, services);
|
||||
}
|
||||
else
|
||||
{
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
private static SingleLiteralElement CreateSingle(string image, IServiceProvider services)
|
||||
{
|
||||
if (image.EndsWith("f", StringComparison.OrdinalIgnoreCase) == true)
|
||||
{
|
||||
image = image.Remove(image.Length - 1);
|
||||
return SingleLiteralElement.Parse(image, services);
|
||||
}
|
||||
else
|
||||
{
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
private static DecimalLiteralElement CreateDecimal(string image, IServiceProvider services)
|
||||
{
|
||||
if (image.EndsWith("m", StringComparison.OrdinalIgnoreCase) == true)
|
||||
{
|
||||
image = image.Remove(image.Length - 1);
|
||||
return DecimalLiteralElement.Parse(image, services);
|
||||
}
|
||||
else
|
||||
{
|
||||
return null;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
Reference in New Issue
Block a user