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;
|
object constantValue, persistData = null;
|
||||||
var constantTypeSchema = ResolveTypeFromQualifiedName(constant.TypeName);
|
var constantTypeSchema = ResolveTypeFromQualifiedName(constant.TypeName);
|
||||||
|
|
||||||
if (constant is EncodedConstantDirective encodedConstant)
|
if (constant is StringEncodedConstantDirective encodedConstant)
|
||||||
{
|
{
|
||||||
var parseResult = constantTypeSchema.TypeConverter(encodedConstant.Content, stringTypeSchema, out constantValue);
|
var parseResult = constantTypeSchema.TypeConverter(encodedConstant.Content, stringTypeSchema, out constantValue);
|
||||||
if (parseResult.Failed)
|
if (parseResult.Failed)
|
||||||
|
|||||||
@@ -4,6 +4,7 @@ using Microsoft.Iris.Markup;
|
|||||||
using System;
|
using System;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
|
using System.Runtime.InteropServices;
|
||||||
using System.Xml.Linq;
|
using System.Xml.Linq;
|
||||||
|
|
||||||
namespace Microsoft.Iris.Asm;
|
namespace Microsoft.Iris.Asm;
|
||||||
@@ -226,17 +227,28 @@ public class Disassembler
|
|||||||
if (constantValue is IStringEncodable encodable)
|
if (constantValue is IStringEncodable encodable)
|
||||||
{
|
{
|
||||||
var encodedValue = encodable.EncodeString();
|
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))
|
else if (typeSchema.SupportsTypeConversion(stringTypeSchema))
|
||||||
{
|
{
|
||||||
var encodedValue = constantValue.ToString();
|
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);
|
ByteCodeWriter writer = new();
|
||||||
yield return new EncodedConstantDirective(constantName, qualifiedTypeName, constantLayoutString);
|
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
|
else
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -1,5 +1,7 @@
|
|||||||
using Microsoft.Iris.Asm.Models;
|
using Microsoft.Iris.Asm.Models;
|
||||||
using Sprache;
|
using Sprache;
|
||||||
|
using System;
|
||||||
|
using System.Globalization;
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
|
|
||||||
namespace Microsoft.Iris.Asm;
|
namespace Microsoft.Iris.Asm;
|
||||||
@@ -85,6 +87,10 @@ partial class Lexer
|
|||||||
if (!typeNameResult.WasSuccessful)
|
if (!typeNameResult.WasSuccessful)
|
||||||
return Result.Failure<IDirective>(input, "Invalid constant directive", ["Expected qualified name of type to construct"]);
|
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);
|
var openBracketResult = Parse.Char('(').Token()(input);
|
||||||
input = openBracketResult.Remainder;
|
input = openBracketResult.Remainder;
|
||||||
if (!openBracketResult.WasSuccessful)
|
if (!openBracketResult.WasSuccessful)
|
||||||
@@ -100,12 +106,57 @@ partial class Lexer
|
|||||||
if (!closeBracketResult.WasSuccessful)
|
if (!closeBracketResult.WasSuccessful)
|
||||||
return Result.Failure<IDirective>(input, "Invalid constant directive", ["Expected ')'"]);
|
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)
|
||||||
|
{
|
||||||
|
directive = new StringEncodedConstantDirective(constantName, typeName, contentResult.Value)
|
||||||
{
|
{
|
||||||
Line = line,
|
Line = line,
|
||||||
Column = column,
|
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;
|
break;
|
||||||
|
|
||||||
case "EXPORT":
|
case "EXPORT":
|
||||||
|
|||||||
@@ -1,4 +1,7 @@
|
|||||||
namespace Microsoft.Iris.Asm.Models;
|
using System;
|
||||||
|
using System.Linq;
|
||||||
|
|
||||||
|
namespace Microsoft.Iris.Asm.Models;
|
||||||
|
|
||||||
public record SectionDirective : Directive
|
public record SectionDirective : Directive
|
||||||
{
|
{
|
||||||
@@ -28,9 +31,9 @@ public record ConstantDirective : Directive
|
|||||||
public override string ToString() => $"{base.ToString()} {Name} = {Constructor}";
|
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})")
|
: base(name, typeName, $"{typeName}({content})")
|
||||||
{
|
{
|
||||||
Content = content;
|
Content = content;
|
||||||
@@ -41,6 +44,34 @@ public record EncodedConstantDirective : ConstantDirective
|
|||||||
public override string ToString() => base.ToString();
|
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 record ExportDirective : Directive
|
||||||
{
|
{
|
||||||
public ExportDirective(string labelPrefix, uint listenerCount, string baseTypeName) : base("export")
|
public ExportDirective(string labelPrefix, uint listenerCount, string baseTypeName) : base("export")
|
||||||
|
|||||||
Reference in New Issue
Block a user