Generate StatementInformation classes with code generator

This commit is contained in:
Stone_Red
2026-06-11 14:47:59 +02:00
parent 5ad0053ef7
commit 1760b85245
8 changed files with 229 additions and 235 deletions
@@ -4,7 +4,7 @@ namespace YesNt.Interpreter.Runtime;
/// <summary>
/// Exposes the script runtime state accessible to custom statement handlers registered
/// via <see cref="YesNtInterpreter.AddStatement"/>.
/// via <see cref="YesNtInterpreter.AddStatement(YesNt.Interpreter.Runtime.StatementInformation, System.Action{string, YesNt.Interpreter.Runtime.IStatementContext})"/>.
/// </summary>
public interface IStatementContext
{
@@ -24,9 +24,9 @@ public interface IStatementContext
/// <summary>Terminates execution with the given message.</summary>
/// <param name="message">The message written to debug output.</param>
/// <param name="isError">
/// <see langword="true"/> to signal an error termination;
/// <see langword="false"/> for a planned, non-error termination.
/// <param name="stopAllTasks">
/// If <see langword="true"/>, also terminates all tasks spawned by the <c>task</c> statement.
/// If <see langword="false"/>, only terminates the current execution context (main script or individual task).
/// </param>
void Exit(string message, bool isError);
void Exit(string message, bool stopAllTasks);
}
@@ -1,10 +1,8 @@
using System;
using YesNt.Interpreter.Attributes;
namespace YesNt.Interpreter.Runtime;
/// <summary>
/// Pre-calculated statement handler information for faster matching.
/// </summary>
internal record StatementHandler(StatementAttributeContainer Attribute, Action<string> Handler, string FullName);
internal record StatementHandler(StatementInformation Attribute, Action<string> Handler, string FullName);
@@ -1,35 +0,0 @@
using System;
using YesNt.Interpreter.Enums;
namespace YesNt.Interpreter.Runtime;
/// <summary>
/// A read-only snapshot of a registered statement's metadata, used for tooling such as
/// syntax highlighters. Instances are obtained from <see cref="YesNtInterpreter.StatementInformation"/>.
/// </summary>
public class StatementInformation
{
/// <summary>Gets the keyword that identifies this statement in source code.</summary>
public string Name { get; internal set; }
/// <summary>Gets where in the line the keyword is searched for.</summary>
public SearchMode SearchMode { get; internal set; }
/// <summary>Gets which sides of the keyword must be padded with a space.</summary>
public SpaceAround SpaceAround { get; internal set; }
/// <summary>Gets the syntax-highlight color for this statement.</summary>
public ConsoleColor Color { get; internal set; }
/// <summary>
/// Gets a value indicating whether this statement is excluded from syntax highlighting.
/// </summary>
public bool IgnoreSyntaxHighlighting { get; internal set; }
/// <summary>
/// Gets the optional sub-string that must be present in the line for this statement to match,
/// or <see langword="null"/> if no separator is required.
/// </summary>
public string Separator { get; set; }
}
@@ -29,36 +29,17 @@ public class YesNtInterpreter
public event Action<string> OnDebugOutput;
private readonly RuntimeInformation runtimeInfo = new RuntimeInformation();
private Dictionary<StatementAttributeContainer, Action<string>> statements;
private Dictionary<StatementInformation, Action<string>> statements;
private List<StatementHandler> statementHandlers;
private List<List<StatementHandler>> lineMatchingHandlers = [];
private readonly List<KeyValuePair<StaticStatementAttributeContainer, Action>> staticStatements;
private readonly Dictionary<string, List<KeyValuePair<StatementAttributeContainer, Action<string>>>> disabledStatements = [];
private readonly List<KeyValuePair<StaticStatementInformation, Action>> staticStatements;
private readonly Dictionary<string, List<KeyValuePair<StatementInformation, Action<string>>>> disabledStatements = [];
/// <summary>
/// Gets a read-only snapshot of all currently registered statements.
/// Useful for building syntax highlighters or documentation tools.
/// </summary>
public ReadOnlyCollection<StatementInformation> StatementInformation
{
get
{
List<StatementInformation> information = statements.Select(s =>
{
return new StatementInformation()
{
Name = s.Key.Name,
SearchMode = s.Key.SearchMode,
SpaceAround = s.Key.SpaceAround,
Color = s.Key.Color,
IgnoreSyntaxHighlighting = s.Key.IgnoreSyntaxHighlighting,
Separator = s.Key.Separator
};
}).ToList();
return new ReadOnlyCollection<StatementInformation>(information);
}
}
public ReadOnlyCollection<StatementInformation> StatementInformation => statements.Keys.ToList().AsReadOnly();
/// <summary>
/// <see langword="true"/> from the moment <see cref="Prepare(string, bool)"/> (or any
@@ -96,7 +77,7 @@ public class YesNtInterpreter
}
/// <summary>
/// Registers a custom statement using a pre-built <see cref="StatementAttributeContainer"/>.
/// Registers a custom statement using a pre-built <see cref="StatementInformation"/>.
/// If a statement with the same attribute key (identical field values) already exists it will be replaced;
/// otherwise a new entry is added. Built-in statements use distinct attribute instances, so passing a
/// newly constructed attribute with the same name will <b>add</b> a second handler rather than replacing
@@ -106,13 +87,13 @@ public class YesNtInterpreter
/// <param name="attribute">The attribute describing the keyword, search mode, and priority.</param>
/// <param name="handler">
/// The delegate invoked when the statement matches. Receives the argument text
/// (the part of the line after the keyword, unless <see cref="StatementAttributeContainer.KeepStatementInArgs"/> is set).
/// (the part of the line after the keyword, unless <see cref="StatementInformation.KeepStatementInArgs"/> is set).
/// </param>
public void AddStatement(StatementAttributeContainer attribute, Action<string> handler)
public void AddStatement(StatementInformation attribute, Action<string> handler)
{
statements[attribute] = handler;
List<KeyValuePair<StatementAttributeContainer, Action<string>>> entries = [.. statements];
List<KeyValuePair<StatementInformation, Action<string>>> entries = [.. statements];
entries.Sort((a, b) =>
{
int cmp = a.Key.Priority.CompareTo(b.Key.Priority);
@@ -121,7 +102,7 @@ public class YesNtInterpreter
statements = [];
foreach (KeyValuePair<StatementAttributeContainer, Action<string>> entry in entries)
foreach (KeyValuePair<StatementInformation, Action<string>> entry in entries)
{
statements.Add(entry.Key, entry.Value);
}
@@ -139,7 +120,7 @@ public class YesNtInterpreter
/// The delegate invoked when the statement matches. Receives the argument text and the current
/// <see cref="IStatementContext"/> for reading/writing script state.
/// </param>
public void AddStatement(StatementAttributeContainer attribute, Action<string, IStatementContext> handler)
public void AddStatement(StatementInformation attribute, Action<string, IStatementContext> handler)
{
AddStatement(attribute, args => handler(args, runtimeInfo));
}
@@ -153,7 +134,7 @@ public class YesNtInterpreter
/// <param name="handler">The delegate invoked when the statement matches.</param>
public void AddStatement(string name, SearchMode searchMode, SpaceAround spaceAround, Action<string> handler)
{
AddStatement(new StatementAttributeContainer(name, searchMode, spaceAround), handler);
AddStatement(new StatementInformation(name, searchMode, spaceAround), handler);
}
/// <summary>
@@ -169,7 +150,7 @@ public class YesNtInterpreter
/// </param>
public void AddStatement(string name, SearchMode searchMode, SpaceAround spaceAround, Action<string, IStatementContext> handler)
{
AddStatement(new StatementAttributeContainer(name, searchMode, spaceAround), handler);
AddStatement(new StatementInformation(name, searchMode, spaceAround), handler);
}
/// <summary>
@@ -182,7 +163,7 @@ public class YesNtInterpreter
/// <param name="handler">The delegate invoked when the statement matches.</param>
public void AddStatement(string name, SearchMode searchMode, SpaceAround spaceAround, ConsoleColor consoleColor, Action<string> handler)
{
AddStatement(new StatementAttributeContainer(name, searchMode, spaceAround, consoleColor), handler);
AddStatement(new StatementInformation(name, searchMode, spaceAround, consoleColor), handler);
}
/// <summary>
@@ -199,7 +180,7 @@ public class YesNtInterpreter
/// </param>
public void AddStatement(string name, SearchMode searchMode, SpaceAround spaceAround, ConsoleColor consoleColor, Action<string, IStatementContext> handler)
{
AddStatement(new StatementAttributeContainer(name, searchMode, spaceAround, consoleColor), handler);
AddStatement(new StatementInformation(name, searchMode, spaceAround, consoleColor), handler);
}
/// <summary>
@@ -208,7 +189,7 @@ public class YesNtInterpreter
/// <param name="name">The keyword to remove.</param>
public void RemoveStatement(string name)
{
foreach (StatementAttributeContainer key in statements.Keys.Where(k => k.Name == name).ToList())
foreach (StatementInformation key in statements.Keys.Where(k => k.Name == name).ToList())
{
_ = statements.Remove(key);
}
@@ -231,7 +212,7 @@ public class YesNtInterpreter
return;
}
List<KeyValuePair<StatementAttributeContainer, Action<string>>> matching =
List<KeyValuePair<StatementInformation, Action<string>>> matching =
statements.Where(kv => kv.Key.Name == name).ToList();
if (matching.Count == 0)
@@ -241,7 +222,7 @@ public class YesNtInterpreter
disabledStatements[name] = matching;
foreach (KeyValuePair<StatementAttributeContainer, Action<string>> kv in matching)
foreach (KeyValuePair<StatementInformation, Action<string>> kv in matching)
{
statements[kv.Key] = _ => { };
}
@@ -257,12 +238,12 @@ public class YesNtInterpreter
/// <param name="name">The keyword of the statement(s) to re-enable.</param>
public void EnableStatement(string name)
{
if (!disabledStatements.TryGetValue(name, out List<KeyValuePair<StatementAttributeContainer, Action<string>>> saved))
if (!disabledStatements.TryGetValue(name, out List<KeyValuePair<StatementInformation, Action<string>>> saved))
{
return;
}
foreach (KeyValuePair<StatementAttributeContainer, Action<string>> kv in saved)
foreach (KeyValuePair<StatementInformation, Action<string>> kv in saved)
{
statements[kv.Key] = kv.Value;
}
@@ -479,7 +460,7 @@ public class YesNtInterpreter
};
}
foreach (KeyValuePair<StaticStatementAttributeContainer, Action> staticStatement in staticStatements)
foreach (KeyValuePair<StaticStatementInformation, Action> staticStatement in staticStatements)
{
if (!staticStatement.Key.ExecuteInSearchMode && runtimeInfo.IsSearching)
{
@@ -498,7 +479,7 @@ public class YesNtInterpreter
foreach (StatementHandler handler in handlers)
{
StatementAttributeContainer statementAttribute = handler.Attribute;
StatementInformation statementAttribute = handler.Attribute;
if (!statementAttribute.ExecuteInSearchMode && runtimeInfo.IsSearching)
{
@@ -681,7 +662,7 @@ public class YesNtInterpreter
private static bool IsPossibleMatch(string content, StatementHandler handler)
{
StatementAttributeContainer attr = handler.Attribute;
StatementInformation attr = handler.Attribute;
string fullName = handler.FullName;
return attr.SearchMode switch