mirror of
https://github.com/ZuneDev/ZuneUIXTools.git
synced 2026-07-27 13:11:59 -07:00
Add binary encoded constants to lexer and disassembler
This commit is contained in:
@@ -259,7 +259,7 @@ internal class AsmMarkupLoader
|
||||
object constantValue, persistData = null;
|
||||
var constantTypeSchema = ResolveTypeFromQualifiedName(constant.TypeName);
|
||||
|
||||
if (constant is EncodedConstantDirective encodedConstant)
|
||||
if (constant is StringEncodedConstantDirective encodedConstant)
|
||||
{
|
||||
var parseResult = constantTypeSchema.TypeConverter(encodedConstant.Content, stringTypeSchema, out constantValue);
|
||||
if (parseResult.Failed)
|
||||
|
||||
@@ -4,6 +4,7 @@ using Microsoft.Iris.Markup;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Runtime.InteropServices;
|
||||
using System.Xml.Linq;
|
||||
|
||||
namespace Microsoft.Iris.Asm;
|
||||
@@ -226,17 +227,28 @@ public class Disassembler
|
||||
if (constantValue is IStringEncodable encodable)
|
||||
{
|
||||
var encodedValue = encodable.EncodeString();
|
||||
yield return new EncodedConstantDirective(constantName, qualifiedTypeName, encodedValue);
|
||||
yield return new StringEncodedConstantDirective(constantName, qualifiedTypeName, encodedValue);
|
||||
}
|
||||
else if (constantValue is Layout.ILayout constantLayout && Layout.PredefinedLayouts.TryConvertToString(constantLayout, out var constantLayoutString))
|
||||
{
|
||||
qualifiedTypeName = GetQualifiedName(UIXTypes.MapIDToType(UIXTypeID.Layout));
|
||||
yield return new StringEncodedConstantDirective(constantName, qualifiedTypeName, constantLayoutString);
|
||||
}
|
||||
else if (typeSchema.SupportsTypeConversion(stringTypeSchema))
|
||||
{
|
||||
var encodedValue = constantValue.ToString();
|
||||
yield return new EncodedConstantDirective(constantName, qualifiedTypeName, encodedValue);
|
||||
yield return new StringEncodedConstantDirective(constantName, qualifiedTypeName, encodedValue);
|
||||
}
|
||||
else if (constantValue is Layout.ILayout constantLayout && Layout.PredefinedLayouts.TryConvertToString(constantLayout, out var constantLayoutString))
|
||||
else if (typeSchema.SupportsBinaryEncoding)
|
||||
{
|
||||
qualifiedTypeName = GetQualifiedName(typeSchema.Base);
|
||||
yield return new EncodedConstantDirective(constantName, qualifiedTypeName, constantLayoutString);
|
||||
ByteCodeWriter writer = new();
|
||||
typeSchema.EncodeBinary(writer, constantValue);
|
||||
|
||||
var reader = writer.CreateReader();
|
||||
byte[] encodedBytes = new byte[reader.Size];
|
||||
Marshal.Copy(reader.GetAddress(0), encodedBytes, 0, (int)reader.Size);
|
||||
|
||||
yield return new BinaryEncodedConstantDirective(constantName, qualifiedTypeName, encodedBytes);
|
||||
}
|
||||
else
|
||||
{
|
||||
|
||||
@@ -1,5 +1,7 @@
|
||||
using Microsoft.Iris.Asm.Models;
|
||||
using Sprache;
|
||||
using System;
|
||||
using System.Globalization;
|
||||
using System.Linq;
|
||||
|
||||
namespace Microsoft.Iris.Asm;
|
||||
@@ -85,6 +87,10 @@ partial class Lexer
|
||||
if (!typeNameResult.WasSuccessful)
|
||||
return Result.Failure<IDirective>(input, "Invalid constant directive", ["Expected qualified name of type to construct"]);
|
||||
|
||||
var binaryEncodingMarkerResult = Parse.String(".bin")(input);
|
||||
input = binaryEncodingMarkerResult.Remainder;
|
||||
var binaryEncoded = binaryEncodingMarkerResult.WasSuccessful;
|
||||
|
||||
var openBracketResult = Parse.Char('(').Token()(input);
|
||||
input = openBracketResult.Remainder;
|
||||
if (!openBracketResult.WasSuccessful)
|
||||
@@ -100,11 +106,56 @@ partial class Lexer
|
||||
if (!closeBracketResult.WasSuccessful)
|
||||
return Result.Failure<IDirective>(input, "Invalid constant directive", ["Expected ')'"]);
|
||||
|
||||
directive = new EncodedConstantDirective(constNameResult.Value, typeNameResult.Value, contentResult.Value)
|
||||
var constantName = constNameResult.Value;
|
||||
var typeName = typeNameResult.Value;
|
||||
|
||||
if (!binaryEncoded)
|
||||
{
|
||||
Line = line,
|
||||
Column = column,
|
||||
};
|
||||
directive = new StringEncodedConstantDirective(constantName, typeName, contentResult.Value)
|
||||
{
|
||||
Line = line,
|
||||
Column = column,
|
||||
};
|
||||
}
|
||||
else
|
||||
{
|
||||
byte[] constantBytes;
|
||||
var byteParts = contentResult.Value.Split(',');
|
||||
if (byteParts.Length == 1)
|
||||
{
|
||||
var constantStr = byteParts[0].Trim().TrimStart('0', 'x');
|
||||
if (constantStr.Length == 2)
|
||||
{
|
||||
constantBytes = [byte.Parse(constantStr, NumberStyles.HexNumber)];
|
||||
}
|
||||
else if (constantStr.Length == 4)
|
||||
{
|
||||
constantBytes = BitConverter.GetBytes(
|
||||
ushort.Parse(constantStr, NumberStyles.HexNumber));
|
||||
}
|
||||
else if (constantStr.Length == 8)
|
||||
{
|
||||
constantBytes = BitConverter.GetBytes(
|
||||
uint.Parse(constantStr, NumberStyles.HexNumber));
|
||||
}
|
||||
else
|
||||
{
|
||||
return Result.Failure<IDirective>(input, "Invalid constant directive", [$"Expected a 1, 2, or 4 hex number, or a list of bytes."]);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
constantBytes = byteParts
|
||||
.Select(s => byte.Parse(s.TrimStart('0', 'x'), NumberStyles.HexNumber))
|
||||
.ToArray();
|
||||
}
|
||||
|
||||
directive = new BinaryEncodedConstantDirective(constantName, typeName, constantBytes)
|
||||
{
|
||||
Line = line,
|
||||
Column = column,
|
||||
};
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
|
||||
@@ -1,4 +1,7 @@
|
||||
namespace Microsoft.Iris.Asm.Models;
|
||||
using System;
|
||||
using System.Linq;
|
||||
|
||||
namespace Microsoft.Iris.Asm.Models;
|
||||
|
||||
public record SectionDirective : Directive
|
||||
{
|
||||
@@ -28,9 +31,9 @@ public record ConstantDirective : Directive
|
||||
public override string ToString() => $"{base.ToString()} {Name} = {Constructor}";
|
||||
}
|
||||
|
||||
public record EncodedConstantDirective : ConstantDirective
|
||||
public record StringEncodedConstantDirective : ConstantDirective
|
||||
{
|
||||
public EncodedConstantDirective(string name, QualifiedTypeName typeName, string content)
|
||||
public StringEncodedConstantDirective(string name, QualifiedTypeName typeName, string content)
|
||||
: base(name, typeName, $"{typeName}({content})")
|
||||
{
|
||||
Content = content;
|
||||
@@ -41,6 +44,34 @@ public record EncodedConstantDirective : ConstantDirective
|
||||
public override string ToString() => base.ToString();
|
||||
}
|
||||
|
||||
public record BinaryEncodedConstantDirective : ConstantDirective
|
||||
{
|
||||
public BinaryEncodedConstantDirective(string name, QualifiedTypeName typeName, byte[] content)
|
||||
: base(name, typeName, GetConstructor(typeName, content))
|
||||
{
|
||||
Content = content;
|
||||
}
|
||||
|
||||
public byte[] Content { get; }
|
||||
|
||||
public override string ToString() => base.ToString();
|
||||
|
||||
private static string GetConstructor(QualifiedTypeName typeName, byte[] content)
|
||||
{
|
||||
string contentStr;
|
||||
if (content.Length == 1)
|
||||
contentStr = $"0x{content[0]:X2}";
|
||||
else if (content.Length == 2)
|
||||
contentStr = $"0x{BitConverter.ToUInt16(content, 0):X4}";
|
||||
else if (content.Length == 4)
|
||||
contentStr = $"0x{BitConverter.ToUInt32(content, 0):X8}";
|
||||
else
|
||||
contentStr = string.Join(", ", content.Select(b => $"0x{b:X2}"));
|
||||
|
||||
return $"{typeName}.bin({contentStr})";
|
||||
}
|
||||
}
|
||||
|
||||
public record ExportDirective : Directive
|
||||
{
|
||||
public ExportDirective(string labelPrefix, uint listenerCount, string baseTypeName) : base("export")
|
||||
|
||||
Reference in New Issue
Block a user