Enhance parser and add a few functions, fix hex parsing #4
@ -78,16 +78,23 @@ namespace XNeedle.Parser
|
||||
string.Join(",", parameters.Select(e => e.Type.Name))));
|
||||
}
|
||||
|
||||
// This needs to match as one atomic token, else with a separate String("0x") the 0 is consumed,
|
||||
// which triggers a parsing error on single zero numbers
|
||||
public static readonly Parser<string> HexNumber =
|
||||
from prefix in Parse.String("0x").Token()
|
||||
from number in Parse.Char(char.IsAsciiHexDigit, "hexadecimal digit").AtLeastOnce().Text()
|
||||
select number;
|
||||
Parse.Regex(@"0x[0-9a-fA-F]+").Token()
|
||||
.Select(s => s.Substring(2));
|
||||
|
||||
public static readonly Parser<string> BooleanLiteral =
|
||||
from value in Parse.String("true").XOr(Parse.String("false")).Text()
|
||||
select value;
|
||||
|
||||
static readonly Parser<Expression> NumberConstant =
|
||||
HexNumber.Select(x => Expression.Constant(int.Parse(x, System.Globalization.NumberStyles.HexNumber)))
|
||||
HexNumber.Select(x => Expression.Constant((double)int.Parse(x, System.Globalization.NumberStyles.HexNumber)))
|
||||
.XOr(BooleanLiteral.Select(x => Expression.Constant(x == "true" ? 1.0 : 0.0)))
|
||||
.XOr(Parse.Decimal.Select(x => Expression.Constant(double.Parse(x))))
|
||||
.Named("number");
|
||||
|
||||
|
||||
private static readonly Parser<Expression> StringConstant =
|
||||
from open in Parse.Char('"')
|
||||
from value in Parse.CharExcept('"').Many().Text()
|
||||
|
||||
@ -1,4 +1,5 @@
|
||||
using System;
|
||||
using System.Globalization;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using Sprache;
|
||||
@ -12,12 +13,54 @@ namespace XNeedle.Transformation
|
||||
{
|
||||
public class ContextFunctions
|
||||
{
|
||||
public static string hexlit(Context ctx, int value)
|
||||
|
||||
public static double num(Context ctx, string value, double numbase = 10)
|
||||
{
|
||||
if (string.IsNullOrWhiteSpace(value))
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
string cleanedValue = value.Trim();
|
||||
|
||||
if (numbase != 10)
|
||||
{
|
||||
cleanedValue = cleanedValue.TrimStart('0');
|
||||
cleanedValue = cleanedValue.TrimStart('x');
|
||||
|
||||
// Convert to Int64 to not lose any fidelity
|
||||
return Convert.ToInt64(cleanedValue, (int)numbase);
|
||||
}
|
||||
|
||||
return double.Parse(cleanedValue, CultureInfo.InvariantCulture);
|
||||
}
|
||||
public static string str(Context ctx, double value, double numbase = 10)
|
||||
{
|
||||
if (numbase == 10)
|
||||
{
|
||||
return $"{value}";
|
||||
}
|
||||
|
||||
// Ignore fraction for other bases by casting to long
|
||||
return Convert.ToString((long)value, (int)numbase);
|
||||
}
|
||||
|
||||
public static string hexlit(Context ctx, double value)
|
||||
{
|
||||
uint v = (uint)value;
|
||||
return $"#x{v:x8}";
|
||||
}
|
||||
|
||||
public static double parselit(Context ctx, string literal, double numbase = 16)
|
||||
{
|
||||
if (string.IsNullOrWhiteSpace(literal) || literal.Length <= 2)
|
||||
{
|
||||
throw new ArgumentException($"Cannot parse literal \"{literal}\"");
|
||||
}
|
||||
|
||||
return (double)Convert.ToInt32(literal.Substring(2), (int)numbase);
|
||||
}
|
||||
|
||||
public static string lower(Context ctx, string text)
|
||||
{
|
||||
return text.ToLower();
|
||||
@ -70,7 +113,7 @@ namespace XNeedle.Transformation
|
||||
return reflected;
|
||||
}
|
||||
|
||||
public static int crc32(Context ctx, int poly = 0x04C11DB7, int init = 0, int xorOut = 0, bool reflected = false)
|
||||
public static double crc32(Context ctx, double poly = 0x04C11DB7, double init = 0, double xorOut = 0, double reflected = 0.0)
|
||||
{
|
||||
if (ctx.Node is null)
|
||||
return 0;
|
||||
@ -88,7 +131,7 @@ namespace XNeedle.Transformation
|
||||
byte[] fragBytes = Encoding.UTF8.GetBytes(data);
|
||||
|
||||
// Step 3: Digest into CRC32 using parameterized CRC32 - by default MPEG-2
|
||||
return (int)ComputeCrc32(fragBytes, (uint)poly, (uint)init, (uint)xorOut, reflected);
|
||||
return (double)ComputeCrc32(fragBytes, (uint)poly, (uint)init, (uint)xorOut, reflected == 1.0);
|
||||
}
|
||||
|
||||
public static string text(Context ctx)
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user