mirror of
https://github.com/ZuneDev/ZuneUIXTools.git
synced 2026-07-27 13:11:59 -07:00
Add section directives
This commit is contained in:
@@ -1,12 +1,12 @@
|
||||
using Microsoft.Iris.Asm.Models;
|
||||
using Microsoft.Iris.Data;
|
||||
using Microsoft.Iris.Library;
|
||||
using Microsoft.Iris.Markup;
|
||||
using Microsoft.Iris.Session;
|
||||
using Sprache;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Runtime.InteropServices;
|
||||
using System.Text;
|
||||
|
||||
namespace Microsoft.Iris.Asm;
|
||||
@@ -15,15 +15,18 @@ internal class AsmMarkupLoader
|
||||
{
|
||||
private string _asmSource;
|
||||
private Program _program;
|
||||
private bool _hasErrors;
|
||||
private LoadPass _currentValidationPass;
|
||||
private readonly AsmMarkupLoadResult _loadResult;
|
||||
private bool _usingSharedBinaryDataTable;
|
||||
private SourceMarkupImportTables _importTables;
|
||||
private Dictionary<string, LoadResult> _importedNamespaces = new();
|
||||
|
||||
private readonly Dictionary<string, LoadResult> _importedNamespaces = new();
|
||||
private readonly HashSet<string> _referencedNamespaces = new();
|
||||
|
||||
protected AsmMarkupLoader(AsmMarkupLoadResult loadResult) => _loadResult = loadResult;
|
||||
|
||||
public bool HasErrors { get; protected set; }
|
||||
|
||||
internal static unsafe AsmMarkupLoader Load(AsmMarkupLoadResult loadResult, Resource resource)
|
||||
{
|
||||
AsmMarkupLoader owner = new(loadResult);
|
||||
@@ -50,9 +53,10 @@ internal class AsmMarkupLoader
|
||||
|
||||
public void MarkHasErrors()
|
||||
{
|
||||
if (_hasErrors)
|
||||
if (HasErrors)
|
||||
return;
|
||||
_hasErrors = true;
|
||||
|
||||
HasErrors = true;
|
||||
_loadResult.MarkLoadFailed();
|
||||
}
|
||||
|
||||
@@ -128,17 +132,87 @@ internal class AsmMarkupLoader
|
||||
//foreach (ValidateAlias alias in _program.AliasList)
|
||||
// alias.Validate(_currentValidationPass);
|
||||
|
||||
//if (_currentValidationPass == LoadPass.Full)
|
||||
//{
|
||||
// for (ValidateNamespace validateNamespace = _program.XmlnsList; validateNamespace != null; validateNamespace = validateNamespace.Next)
|
||||
// {
|
||||
// if (!_referencedNamespaces.ContainsKey(validateNamespace.Prefix))
|
||||
// ErrorManager.ReportWarning(validateNamespace.Line, validateNamespace.Column, "Unreferenced namespace {0}", validateNamespace.Prefix);
|
||||
// }
|
||||
//}
|
||||
if (_currentValidationPass == LoadPass.Full)
|
||||
{
|
||||
foreach (var nsImport in _program.Imports.OfType<NamespaceImport>())
|
||||
{
|
||||
if (!_referencedNamespaces.Contains(nsImport.Name))
|
||||
ErrorManager.ReportWarning(nsImport.Line, nsImport.Column, $"Unreferenced namespace '{nsImport.Name}'");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//CompleteValidationPass();
|
||||
if (_currentValidationPass == LoadPass.DeclareTypes)
|
||||
{
|
||||
//_loadResult.SetExportTable(PrepareExportTable());
|
||||
//_loadResult.SetAliasTable(PrepareAliasTable());
|
||||
}
|
||||
else if (_currentValidationPass == LoadPass.PopulatePublicModel)
|
||||
{
|
||||
if (_program == null)
|
||||
return;
|
||||
|
||||
//foreach (ValidateClass validateClass in _parseResult.ClassList)
|
||||
// validateClass.TypeExport?.BuildProperties();
|
||||
}
|
||||
else
|
||||
{
|
||||
if (_currentValidationPass != LoadPass.Full)
|
||||
return;
|
||||
|
||||
if (HasErrors)
|
||||
_loadResult.MarkLoadFailed();
|
||||
|
||||
MarkupImportTables importTables = null;
|
||||
if (_importTables != null)
|
||||
{
|
||||
importTables = _importTables.PrepareImportTables();
|
||||
_loadResult.SetImportTables(importTables);
|
||||
}
|
||||
|
||||
MarkupLineNumberTable lineNumberTable = new MarkupLineNumberTable();
|
||||
MarkupConstantsTable constantsTable = _loadResult.BinaryDataTable == null
|
||||
? new MarkupConstantsTable()
|
||||
: _loadResult.BinaryDataTable.ConstantsTable;
|
||||
|
||||
_loadResult.SetDataMappingsTable(PrepareDataMappingTable());
|
||||
_loadResult.ValidationComplete();
|
||||
|
||||
ByteCodeReader reader = null;
|
||||
if (!HasErrors)
|
||||
EncodeOBJECTSection();
|
||||
// reader = new MarkupEncoder(importTables, constantsTable, lineNumberTable).EncodeOBJECTSection(_parseResult, _loadResult.Uri, null);
|
||||
|
||||
if (!_usingSharedBinaryDataTable)
|
||||
{
|
||||
constantsTable.PrepareForRuntimeUse();
|
||||
_loadResult.SetConstantsTable(constantsTable);
|
||||
}
|
||||
|
||||
lineNumberTable.PrepareForRuntimeUse();
|
||||
_loadResult.SetLineNumberTable(lineNumberTable);
|
||||
|
||||
if (reader != null)
|
||||
_loadResult.SetObjectSection(reader);
|
||||
|
||||
_loadResult.SetDependenciesTable(PrepareDependenciesTable());
|
||||
|
||||
if (!MarkupSystem.TrackAdditionalMetadata)
|
||||
_program = null;
|
||||
|
||||
//foreach (DisposableObject validateObject in _validateObjects)
|
||||
// validateObject.Dispose(this);
|
||||
}
|
||||
}
|
||||
|
||||
private LoadResult[] PrepareDependenciesTable()
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
|
||||
private MarkupDataMapping[] PrepareDataMappingTable()
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
|
||||
public void ReportError(string error, int line, int column)
|
||||
@@ -146,4 +220,9 @@ internal class AsmMarkupLoader
|
||||
MarkHasErrors();
|
||||
ErrorManager.ReportError(line, column, error);
|
||||
}
|
||||
|
||||
private void EncodeOBJECTSection()
|
||||
{
|
||||
var instructions = _program.Body.OfType<Instruction>();
|
||||
}
|
||||
}
|
||||
@@ -39,7 +39,7 @@ public class Disassembler
|
||||
if (scheme == "assembly")
|
||||
{
|
||||
// Assume the URI represents a C# namespace
|
||||
name = uri.Split('.', '/', '\\')[^1];
|
||||
name = uri.Split('.', '/', '\\', '!')[^1];
|
||||
|
||||
// Remove the extra assembly info
|
||||
uri = uri.Split(',')[0];
|
||||
@@ -48,7 +48,7 @@ public class Disassembler
|
||||
{
|
||||
// Assume the URI represents a file,
|
||||
// skip the extension
|
||||
name = uri.Split('.', '/', '\\')[^2];
|
||||
name = uri.Split('.', '/', '\\', '!')[^2];
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -13,9 +13,22 @@ partial class Lexer
|
||||
var line = input.Line;
|
||||
var column = input.Column;
|
||||
|
||||
var directiveResult = ParseDirective(input);
|
||||
if (directiveResult.WasSuccessful)
|
||||
{
|
||||
input = directiveResult.Remainder;
|
||||
var directive = directiveResult.Value;
|
||||
if (directive is not IBodyItem directiveBodyItem)
|
||||
return Result.Failure<IBodyItem>(input, "Invalid code", [$"The {directive.Identifier} directive cannot be placed in the body of a program"]);
|
||||
|
||||
directive.Line = line;
|
||||
directive.Column = column;
|
||||
return Result.Success(directiveBodyItem, input);
|
||||
}
|
||||
|
||||
var identifierResult = Parse.Letter.AtLeastOnce().Text().Invoke(input);
|
||||
if (!identifierResult.WasSuccessful)
|
||||
return Result.Failure<Instruction>(input, "Invalid code", []);
|
||||
return Result.Failure<IBodyItem>(input, "Invalid code", []);
|
||||
|
||||
input = identifierResult.Remainder;
|
||||
var identifier = identifierResult.Value;
|
||||
@@ -54,5 +67,4 @@ partial class Lexer
|
||||
|
||||
return Result.Success(bodyItem, input);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -0,0 +1,52 @@
|
||||
using Microsoft.Iris.Asm.Models;
|
||||
using Sprache;
|
||||
|
||||
namespace Microsoft.Iris.Asm;
|
||||
|
||||
partial class Lexer
|
||||
{
|
||||
private static IResult<IDirective> ParseDirective(IInput input)
|
||||
{
|
||||
input = ConsumeWhitespace(input);
|
||||
var line = input.Line;
|
||||
var column = input.Column;
|
||||
|
||||
var directiveBeginResult = Parse.String(".")(input);
|
||||
input = directiveBeginResult.Remainder;
|
||||
if (!directiveBeginResult.WasSuccessful)
|
||||
return Result.Failure<IDirective>(input, "Invalid directive", ["Expected '.', followed by an identifier"]);
|
||||
|
||||
var directiveIdResult = Parse.Letter.AtLeastOnce().Text()(input);
|
||||
input = directiveIdResult.Remainder;
|
||||
if (!directiveIdResult.WasSuccessful)
|
||||
return Result.Failure<IDirective>(input, "Invalid directive", ["Expected an identifier"]);
|
||||
|
||||
IDirective directive;
|
||||
switch (directiveIdResult.Value.ToUpperInvariant())
|
||||
{
|
||||
case "IMPORT":
|
||||
return ParseImportAsDirective(input);
|
||||
|
||||
case "SECTION":
|
||||
if (StatementEnd(input).WasSuccessful)
|
||||
return Result.Failure<IImport>(input, "Invalid section directive", ["Expected a section name"]);
|
||||
|
||||
var sectionNameResult = Parse.Letter.AtLeastOnce().Token().Text()(input);
|
||||
input = sectionNameResult.Remainder;
|
||||
if (!sectionNameResult.WasSuccessful)
|
||||
return Result.Failure<IImport>(input, "Invalid section name", ["Expected a section name containing only letters"]);
|
||||
|
||||
directive = new SectionDirective(sectionNameResult.Value)
|
||||
{
|
||||
Line = line,
|
||||
Column = column,
|
||||
};
|
||||
break;
|
||||
|
||||
default:
|
||||
return Result.Failure<IImport>(input, $"Unknown import type '{directiveIdResult.Value}'", ["Expected 'import' or 'section'"]);
|
||||
}
|
||||
|
||||
return Result.Success(directive, input);
|
||||
}
|
||||
}
|
||||
@@ -9,11 +9,20 @@ partial class Lexer
|
||||
{
|
||||
input = ConsumeWhitespace(input);
|
||||
|
||||
var importDirectiveResult = Parse.String(".import-")(input);
|
||||
var importDirectiveResult = Parse.String(".import")(input);
|
||||
input = importDirectiveResult.Remainder;
|
||||
if (!importDirectiveResult.WasSuccessful)
|
||||
return Result.Failure<IImport>(input, "Invalid import directive", ["Expected '.import'"]);
|
||||
|
||||
return ParseImportAsDirective(input);
|
||||
}
|
||||
|
||||
private static IResult<IImport> ParseImportAsDirective(IInput input)
|
||||
{
|
||||
if (input.Current != '-' || input.AtEnd)
|
||||
return Result.Failure<IImport>(input, "Invalid import type", ["An import type must be specified"]);
|
||||
input = input.Advance();
|
||||
|
||||
var importTypeResult = Parse.Letter.AtLeastOnce().Text()(input);
|
||||
input = importTypeResult.Remainder;
|
||||
if (!importTypeResult.WasSuccessful)
|
||||
|
||||
@@ -12,13 +12,10 @@ public static partial class Lexer
|
||||
|
||||
public static readonly Parser<string> StatementEnd = Parse.Char(';').Return(";").Or(Parse.LineTerminator);
|
||||
|
||||
public static readonly Parser<string> SectionDirective =
|
||||
from _ in Parse.String(".section").Token()
|
||||
from sectionId in Parse.Letter.AtLeastOnce().Text()
|
||||
select sectionId;
|
||||
|
||||
public static readonly Parser<IImport> Import = ParseImport;
|
||||
|
||||
public static readonly Parser<IDirective> Directive = ParseDirective;
|
||||
|
||||
public static readonly Parser<IBodyItem> BodyItem = ParseBodyItem;
|
||||
|
||||
public static readonly Parser<Program> Program =
|
||||
|
||||
@@ -0,0 +1,13 @@
|
||||
namespace Microsoft.Iris.Asm.Models;
|
||||
|
||||
public record SectionDirective : Directive, IBodyItem
|
||||
{
|
||||
public SectionDirective(string name) : base("section")
|
||||
{
|
||||
Name = name;
|
||||
}
|
||||
|
||||
public string Name { get; init; }
|
||||
|
||||
public override string ToString() => $"{base.ToString()} {Name}";
|
||||
}
|
||||
@@ -18,6 +18,9 @@ public class Assembly(ITestOutputHelper output)
|
||||
.import-ns Me as me
|
||||
.import-ns assembly://UIX/Microsoft.Iris as iris
|
||||
|
||||
.section data
|
||||
|
||||
.section object
|
||||
main:
|
||||
COBJ 2
|
||||
PSHC 0
|
||||
@@ -34,7 +37,7 @@ main:
|
||||
|
||||
Assert.NotNull(ast);
|
||||
Assert.Equal(2, ast.Imports.Count());
|
||||
Assert.Equal(9, ast.Body.Count());
|
||||
Assert.Equal(9 + 2, ast.Body.Count());
|
||||
}
|
||||
|
||||
[Fact]
|
||||
|
||||
Reference in New Issue
Block a user