More constant operand work in assembler

This commit is contained in:
Yoshi Askharoun
2024-02-12 23:14:53 -06:00
parent 03859bec6e
commit 6bc1880f2c
4 changed files with 39 additions and 18 deletions
+21 -5
View File
@@ -20,6 +20,7 @@ internal class AsmMarkupLoader
private ObjectSection _objectSection; private ObjectSection _objectSection;
private readonly Dictionary<string, LoadResult> _importedNamespaces = new(); private readonly Dictionary<string, LoadResult> _importedNamespaces = new();
private readonly Dictionary<string, ushort> _constants = new();
private readonly HashSet<string> _referencedNamespaces = new(); private readonly HashSet<string> _referencedNamespaces = new();
internal unsafe AsmMarkupLoader(AsmMarkupLoadResult loadResult, Resource resource) internal unsafe AsmMarkupLoader(AsmMarkupLoadResult loadResult, Resource resource)
@@ -51,6 +52,8 @@ internal class AsmMarkupLoader
{ {
if (prefix == null) if (prefix == null)
return MarkupSystem.UIXGlobal; return MarkupSystem.UIXGlobal;
if (prefix == "me")
return _loadResult;
return _importedNamespaces[prefix]; return _importedNamespaces[prefix];
} }
@@ -155,7 +158,13 @@ internal class AsmMarkupLoader
if (_currentValidationPass == LoadPass.Full) if (_currentValidationPass == LoadPass.Full)
{ {
foreach (var nsImport in Program.Directives.OfType<NamespaceImport>()) foreach (var typeImport in Program.Imports.OfType<TypeImport>())
{
var typeSchema = ResolveTypeFromQualifiedName(typeImport.QualifiedName);
_importTables.ImportedTypes.Add(typeSchema);
}
foreach (var nsImport in Program.Imports.OfType<NamespaceImport>())
{ {
if (!_referencedNamespaces.Contains(nsImport.Name)) if (!_referencedNamespaces.Contains(nsImport.Name))
ErrorManager.ReportWarning(nsImport.Line, nsImport.Column, $"Unreferenced namespace '{nsImport.Name}'"); ErrorManager.ReportWarning(nsImport.Line, nsImport.Column, $"Unreferenced namespace '{nsImport.Name}'");
@@ -228,20 +237,27 @@ internal class AsmMarkupLoader
{ {
var propName = attr.Name.LocalName; var propName = attr.Name.LocalName;
var prop = constantTypeSchema.FindProperty(propName); var prop = constantTypeSchema.FindProperty(propName);
prop.SetValue(ref constantValue, attr.Value);
var propConvertResult = prop.PropertyType.TypeConverter(attr.Value, stringTypeSchema, out var propValue);
if (propConvertResult.Failed)
{
ReportError($"Failed to set {constantTypeSchema.Name}.{propName}", constant);
continue;
} }
ReportError($"'{constant.TypeName}' cannot be constructed from a string, and UIXA does not yet support XML construction.", constant); prop.SetValue(ref constantValue, propValue);
continue; }
} }
var mode = constantTypeSchema.SupportsBinaryEncoding var mode = constantTypeSchema.SupportsBinaryEncoding
? MarkupConstantPersistMode.Binary ? MarkupConstantPersistMode.Binary
: MarkupConstantPersistMode.FromString; : MarkupConstantPersistMode.FromString;
constantsTable.Add(constantTypeSchema, constantValue, mode); var constantIndex = (ushort)constantsTable.Add(constantTypeSchema, constantValue, mode);
_constants.Add(constant.Name, constantIndex);
} }
_objectSection.Constants = _constants;
reader = _objectSection.Encode(); reader = _objectSection.Encode();
UpdateExportOffsets(); UpdateExportOffsets();
} }
+4 -1
View File
@@ -67,7 +67,10 @@ partial class Lexer
return Result.Failure<IDirective>(input, "Invalid constant directive", ["Expected valid XML"]); return Result.Failure<IDirective>(input, "Invalid constant directive", ["Expected valid XML"]);
var xmlElem = System.Xml.Linq.XElement.Parse($"{xmlPartResult.Value}/>"); var xmlElem = System.Xml.Linq.XElement.Parse($"{xmlPartResult.Value}/>");
QualifiedTypeName typeName = new(xmlElem.Name.NamespaceName, xmlElem.Name.LocalName); var xmlPrefix = xmlElem.Name.NamespaceName == string.Empty
? null : xmlElem.Name.NamespaceName;
QualifiedTypeName typeName = new(xmlPrefix, xmlElem.Name.LocalName);
var content = xmlElem.ToString(System.Xml.Linq.SaveOptions.DisableFormatting); var content = xmlElem.ToString(System.Xml.Linq.SaveOptions.DisableFormatting);
directive = new ConstantDirective(constNameResult.Value, typeName, content) directive = new ConstantDirective(constNameResult.Value, typeName, content)
+12 -10
View File
@@ -8,29 +8,26 @@ namespace Microsoft.Iris.Asm;
public class ObjectSection public class ObjectSection
{ {
readonly IEnumerable<IBodyItem> _body; readonly Program _program;
readonly MarkupLoadResult _loadResult; readonly MarkupLoadResult _loadResult;
Dictionary<string, uint> _labelOffsetMap; Dictionary<string, uint> _labelOffsetMap;
public ObjectSection(IEnumerable<IBodyItem> body, MarkupLoadResult loadResult) public ObjectSection(Program program, MarkupLoadResult loadResult)
{ {
_body = body; _program = program;
_loadResult = loadResult; _loadResult = loadResult;
} }
public ObjectSection(Program program, MarkupLoadResult loadResult)
: this(program.Body, loadResult)
{
}
public IReadOnlyDictionary<string, uint> LabelOffsetMap => _labelOffsetMap; public IReadOnlyDictionary<string, uint> LabelOffsetMap => _labelOffsetMap;
public IReadOnlyDictionary<string, ushort> Constants { get; set; }
public ByteCodeReader Encode() public ByteCodeReader Encode()
{ {
ByteCodeWriter writer = new(); ByteCodeWriter writer = new();
_labelOffsetMap = new(); _labelOffsetMap = new();
foreach (var bodyItem in _body) foreach (var bodyItem in _program.Body)
{ {
var offset = writer.DataSize; var offset = writer.DataSize;
@@ -50,7 +47,12 @@ public class ObjectSection
foreach (var operand in instruction.Operands) foreach (var operand in instruction.Operands)
{ {
switch (operand.Value) object operandValue = operand.Value;
if (operand is OperandReference operandRef)
operandValue = Constants[operandRef.ConstantName];
switch (operandValue)
{ {
case OperationType opType: case OperationType opType:
writer.WriteByte((byte)opType); writer.WriteByte((byte)opType);