Add type imports and exports to parser

This commit is contained in:
Yoshi Askharoun
2024-02-08 10:51:08 -06:00
parent 9e8ffe786b
commit 3c2ae6a9cd
6 changed files with 83 additions and 9 deletions
+19 -2
View File
@@ -1,5 +1,6 @@
using Microsoft.Iris.Asm.Models;
using Sprache;
using System.Linq;
namespace Microsoft.Iris.Asm;
@@ -16,7 +17,7 @@ partial class Lexer
if (!directiveBeginResult.WasSuccessful)
return Result.Failure<IDirective>(input, "Invalid directive", ["Expected '.', followed by an identifier"]);
var directiveIdResult = Parse.Letter.AtLeastOnce().Text()(input);
var directiveIdResult = WordText(input);
input = directiveIdResult.Remainder;
if (!directiveIdResult.WasSuccessful)
return Result.Failure<IDirective>(input, "Invalid directive", ["Expected an identifier"]);
@@ -43,8 +44,24 @@ partial class Lexer
};
break;
case "EXPORT":
if (StatementEnd(input).WasSuccessful)
return Result.Failure<IImport>(input, "Invalid export directive", ["Expected export information"]);
var labelPrefixResult = AlphanumericText.Token()(input);
input = labelPrefixResult.Remainder;
if (!labelPrefixResult.WasSuccessful)
return Result.Failure<IImport>(input, "Invalid export directive", ["Expected prefix of labels to export"]);
directive = new ExportDirective(labelPrefixResult.Value)
{
Line = line,
Column = column,
};
break;
default:
return Result.Failure<IImport>(input, $"Unknown import type '{directiveIdResult.Value}'", ["Expected 'import' or 'section'"]);
return Result.Failure<IImport>(input, $"Unknown import type '{directiveIdResult.Value}'", ["Expected 'export', 'import', or 'section'"]);
}
return Result.Success(directive, input);
+17 -1
View File
@@ -23,7 +23,7 @@ partial class Lexer
return Result.Failure<IImport>(input, "Invalid import type", ["An import type must be specified"]);
input = input.Advance();
var importTypeResult = Parse.Letter.AtLeastOnce().Text()(input);
var importTypeResult = WordText(input);
input = importTypeResult.Remainder;
if (!importTypeResult.WasSuccessful)
return Result.Failure<IImport>(input, "Invalid import type", ["Expected 'ns'"]);
@@ -47,6 +47,22 @@ partial class Lexer
import = new NamespaceImport(uriResult.Value, nameResult.Value);
break;
case "TYPE":
var typePrefixResult = WordText.Token()(input);
input = typePrefixResult.Remainder;
if (!typePrefixResult.WasSuccessful)
return Result.Failure<IImport>(input, "Invalid type import", ["Expected a valid namespace prefix"]);
input = Parse.Char(':')(input).Remainder;
var typeNameResult = WordText(input);
input = typeNameResult.Remainder;
if (!typeNameResult.WasSuccessful)
return Result.Failure<IImport>(input, "Invalid type import", ["Expected a valid type name"]);
import = new TypeImport(typePrefixResult.Value, typeNameResult.Value);
break;
default:
return Result.Failure<IImport>(input, $"Unknown import type '{importTypeResult.Value}'", ["Expected 'ns'"]);
}
+4 -2
View File
@@ -8,6 +8,8 @@ public static partial class Lexer
{
public static readonly Parser<string> AlphanumericText = Parse.LetterOrDigit.AtLeastOnce().Text();
public static readonly Parser<string> WordText = Parse.Letter.AtLeastOnce().Text();
public static readonly Parser<string> Uri = Parse.LetterOrDigit.Or(Parse.Chars(":/!._-")).AtLeastOnce().Text();
public static readonly Parser<string> StatementEnd = Parse.Char(';').Return(";").Or(Parse.LineTerminator);
@@ -19,9 +21,9 @@ public static partial class Lexer
public static readonly Parser<IBodyItem> BodyItem = ParseBodyItem;
public static readonly Parser<Program> Program =
from imports in Import.Token().Many()
from directives in Directive.Many()
from body in BodyItem.Many()
select new Program(imports, body);
select new Program(directives, body);
private static IInput ConsumeWhitespace(IInput input) => Parse.WhiteSpace.Many()(input).Remainder;
}
+20
View File
@@ -11,3 +11,23 @@ public record SectionDirective : Directive, IBodyItem
public override string ToString() => $"{base.ToString()} {Name}";
}
public record ExportDirective : Directive
{
public ExportDirective(string labelPrefix) : base("export")
{
LabelPrefix = labelPrefix;
}
public string LabelPrefix { get; init; }
public override string ToString() => $"{base.ToString()} {LabelPrefix}";
public string InitializePropertiesLabel => LabelPrefix + "_prop";
public string InitializeLocalInputLabel => LabelPrefix + "_locl";
public string InitializeContentLabel => LabelPrefix + "_cont";
public string InitialEvaluateOffsetsLabelPrefix => LabelPrefix + "_evali_";
public string FinalEvaluateOffsetsLabelPrefix => LabelPrefix + "_evalf_";
public string RefreshGroupOffsetsLabelPrefix => LabelPrefix + "_rfsh_";
}
+20
View File
@@ -13,3 +13,23 @@ public record NamespaceImport : Import
public override string ToString() => $"{base.ToString()} {Uri} as {Name}";
}
public record TypeImport : Import
{
public TypeImport(string namespacePrefix, string name) : base("type")
{
NamespacePrefix = namespacePrefix;
Name = name;
}
public string NamespacePrefix { get; init; }
public string Name { get; init; }
public override string ToString()
{
if (NamespacePrefix is null)
return $"{base.ToString()} {Name}";
else
return $"{base.ToString()} {NamespacePrefix}:{Name}";
}
}
+3 -4
View File
@@ -1,5 +1,4 @@
using Microsoft.Iris.Markup;
using System.Collections.Generic;
using System.Collections.Generic;
using System.Diagnostics;
using System.Linq;
using System.Text;
@@ -26,7 +25,7 @@ public record Operand(object Value, OperandDataType DataType, string Content = n
public override string ToString() => Content ?? Value.ToString();
}
public record Program(IEnumerable<IImport> Imports, IEnumerable<IBodyItem> Body)
public record Program(IEnumerable<IDirective> Directives, IEnumerable<IBodyItem> Body)
{
public override string ToString()
{
@@ -34,7 +33,7 @@ public record Program(IEnumerable<IImport> Imports, IEnumerable<IBodyItem> Body)
const string indent = " ";
StringBuilder sb = new();
sb.AppendJoin(lineEnding, Imports.Select(i => i.ToString()));
sb.AppendJoin(lineEnding, Directives.Select(i => i.ToString()));
sb.Append(lineEnding);
sb.Append(lineEnding);