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 Microsoft.Iris.Asm.Models;
using Sprache; using Sprache;
using System.Linq;
namespace Microsoft.Iris.Asm; namespace Microsoft.Iris.Asm;
@@ -16,7 +17,7 @@ partial class Lexer
if (!directiveBeginResult.WasSuccessful) if (!directiveBeginResult.WasSuccessful)
return Result.Failure<IDirective>(input, "Invalid directive", ["Expected '.', followed by an identifier"]); 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; input = directiveIdResult.Remainder;
if (!directiveIdResult.WasSuccessful) if (!directiveIdResult.WasSuccessful)
return Result.Failure<IDirective>(input, "Invalid directive", ["Expected an identifier"]); return Result.Failure<IDirective>(input, "Invalid directive", ["Expected an identifier"]);
@@ -43,8 +44,24 @@ partial class Lexer
}; };
break; 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: 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); 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"]); return Result.Failure<IImport>(input, "Invalid import type", ["An import type must be specified"]);
input = input.Advance(); input = input.Advance();
var importTypeResult = Parse.Letter.AtLeastOnce().Text()(input); var importTypeResult = WordText(input);
input = importTypeResult.Remainder; input = importTypeResult.Remainder;
if (!importTypeResult.WasSuccessful) if (!importTypeResult.WasSuccessful)
return Result.Failure<IImport>(input, "Invalid import type", ["Expected 'ns'"]); return Result.Failure<IImport>(input, "Invalid import type", ["Expected 'ns'"]);
@@ -47,6 +47,22 @@ partial class Lexer
import = new NamespaceImport(uriResult.Value, nameResult.Value); import = new NamespaceImport(uriResult.Value, nameResult.Value);
break; 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: default:
return Result.Failure<IImport>(input, $"Unknown import type '{importTypeResult.Value}'", ["Expected 'ns'"]); 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> 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> Uri = Parse.LetterOrDigit.Or(Parse.Chars(":/!._-")).AtLeastOnce().Text();
public static readonly Parser<string> StatementEnd = Parse.Char(';').Return(";").Or(Parse.LineTerminator); 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<IBodyItem> BodyItem = ParseBodyItem;
public static readonly Parser<Program> Program = public static readonly Parser<Program> Program =
from imports in Import.Token().Many() from directives in Directive.Many()
from body in BodyItem.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; 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 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 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.Diagnostics;
using System.Linq; using System.Linq;
using System.Text; 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 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() public override string ToString()
{ {
@@ -34,7 +33,7 @@ public record Program(IEnumerable<IImport> Imports, IEnumerable<IBodyItem> Body)
const string indent = " "; const string indent = " ";
StringBuilder sb = new(); 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);
sb.Append(lineEnding); sb.Append(lineEnding);