mirror of
https://github.com/Stone-Red-Code/YesNt-Interpreter.git
synced 2026-09-04 00:56:31 +02:00
Add XML docs
This commit is contained in:
@@ -4,8 +4,19 @@ using System.Text.RegularExpressions;
|
||||
|
||||
namespace YesNt.Interpreter.Utilities;
|
||||
|
||||
/// <summary>
|
||||
/// Provides expression evaluation used by conditional and arithmetic statements.
|
||||
/// </summary>
|
||||
internal static partial class Evaluator
|
||||
{
|
||||
/// <summary>
|
||||
/// Evaluates a boolean condition string such as <c>a == b</c>, <c>x > 3</c>, or <c>true</c>.
|
||||
/// </summary>
|
||||
/// <param name="input">The condition expression, which may contain safe-string encoded values.</param>
|
||||
/// <returns>
|
||||
/// <see langword="true"/> or <see langword="false"/> if the condition could be evaluated;
|
||||
/// <see langword="null"/> if the expression is not a recognised condition form (treated as an error by callers).
|
||||
/// </returns>
|
||||
public static bool? EvaluateCondition(string input)
|
||||
{
|
||||
if (input.ToLower().FromSafeString().Trim() == "true")
|
||||
@@ -68,6 +79,13 @@ internal static partial class Evaluator
|
||||
return null;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Evaluates a numeric arithmetic expression string and returns the result as a string.
|
||||
/// Supports <c>+</c>, <c>-</c>, <c>*</c>, and <c>/</c> operators.
|
||||
/// Adjacent sign characters (<c>++</c>, <c>--</c>, <c>-+</c>, <c>+-</c>) are normalised before evaluation.
|
||||
/// </summary>
|
||||
/// <param name="input">The arithmetic expression to evaluate.</param>
|
||||
/// <returns>The result as a culture-invariant numeric string, or <c>"NaN"</c> if evaluation failed.</returns>
|
||||
public static string Calculate(string input)
|
||||
{
|
||||
input = PlusPlusRegex().Replace(input, "+");
|
||||
|
||||
@@ -11,6 +11,14 @@ public delegate void DataReceivedEventHandler(object sender, DataReceivedEventAr
|
||||
|
||||
internal delegate void UserCallBack(string data);
|
||||
|
||||
/// <summary>
|
||||
/// A workaround replacement for <see cref="System.Diagnostics.Process"/> that fixes a buffering
|
||||
/// issue in <see cref="System.Diagnostics.Process.BeginOutputReadLine"/> / <see cref="System.Diagnostics.Process.BeginErrorReadLine"/>:
|
||||
/// the BCL implementation only delivers data when a newline is encountered, which means partial
|
||||
/// lines are not raised until the process writes another newline or exits.
|
||||
/// <see cref="FixedProcess"/> flushes whatever is in the read buffer immediately, enabling real-time
|
||||
/// output forwarding for interactive child processes.
|
||||
/// </summary>
|
||||
public class FixedProcess : Process
|
||||
{
|
||||
public new event DataReceivedEventHandler OutputDataReceived;
|
||||
|
||||
@@ -6,10 +6,27 @@ using System.Text;
|
||||
|
||||
namespace YesNt.Interpreter.Utilities;
|
||||
|
||||
/// <summary>
|
||||
/// Extension methods for string manipulation used throughout the interpreter.
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// <para>
|
||||
/// YesNt uses a "safe string" encoding to pass values through the interpreter pipeline without
|
||||
/// accidentally triggering keyword matching. Special characters (spaces, operators, punctuation,
|
||||
/// control characters) are replaced with tilde-prefixed three-letter codes
|
||||
/// (e.g. space → <c>~spc</c>, newline → <c>~nli</c>). The mapping is defined in
|
||||
/// <see cref="ReplacementRules"/>. Use <see cref="ToSafeString"/> to encode and
|
||||
/// <see cref="FromSafeString"/> to decode.
|
||||
/// </para>
|
||||
/// </remarks>
|
||||
public static class StringExtensions
|
||||
{
|
||||
private static readonly Dictionary<string, string> reverseReplacementRules;
|
||||
|
||||
/// <summary>
|
||||
/// Gets the table that maps special characters to their safe-string escape codes.
|
||||
/// Keys are the original characters; values are the three-letter tilde codes.
|
||||
/// </summary>
|
||||
public static Dictionary<string, string> ReplacementRules { get; } = new()
|
||||
{
|
||||
{"~", "~til" },
|
||||
@@ -34,6 +51,13 @@ public static class StringExtensions
|
||||
reverseReplacementRules = ReplacementRules.ToDictionary(x => x.Value, x => x.Key);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Encodes a string into safe-string format so that special characters cannot accidentally
|
||||
/// trigger interpreter keyword matching. Each character is wrapped with vertical-tab sentinels
|
||||
/// before rule substitution so that multi-character replacements do not overlap.
|
||||
/// </summary>
|
||||
/// <param name="input">The plain string to encode.</param>
|
||||
/// <returns>The safe-string encoded representation.</returns>
|
||||
public static string ToSafeString(this string input)
|
||||
{
|
||||
StringBuilder output = new StringBuilder();
|
||||
@@ -45,28 +69,53 @@ public static class StringExtensions
|
||||
return ReplaceOnce(output.ToString(), ReplacementRules);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Decodes a safe-string back to its original plain-text form.
|
||||
/// </summary>
|
||||
/// <param name="input">A safe-string encoded string.</param>
|
||||
/// <returns>The decoded plain string.</returns>
|
||||
public static string FromSafeString(this string input)
|
||||
{
|
||||
return ReplaceOnce(input.Replace("\v", string.Empty), reverseReplacementRules);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Tries to parse the string as a <see cref="double"/>, first decoding safe-string encoding
|
||||
/// and normalising decimal separators (comma → period).
|
||||
/// </summary>
|
||||
/// <param name="input">The string to parse (may be safe-string encoded).</param>
|
||||
/// <param name="result">When this method returns, contains the parsed value if successful.</param>
|
||||
/// <returns><see langword="true"/> if parsing succeeded; otherwise <see langword="false"/>.</returns>
|
||||
public static bool ToStandardizedNumber(this string input, out double result)
|
||||
{
|
||||
return double.TryParse(input.FromSafeString().Replace(',', '.'), NumberStyles.Any, CultureInfo.InvariantCulture, out result);
|
||||
}
|
||||
|
||||
/// <summary>Replaces only the first occurrence of <paramref name="oldValue"/> in the string.</summary>
|
||||
/// <param name="input">The source string.</param>
|
||||
/// <param name="oldValue">The substring to find.</param>
|
||||
/// <param name="newValue">The replacement value.</param>
|
||||
/// <returns>A new string with the first occurrence replaced.</returns>
|
||||
public static string ReplaceFirstOccurrence(this string input, string oldValue, string newValue)
|
||||
{
|
||||
int place = input.IndexOf(oldValue);
|
||||
return input.Remove(place, oldValue.Length).Insert(place, newValue);
|
||||
}
|
||||
|
||||
/// <summary>Replaces only the last occurrence of <paramref name="oldValue"/> in the string.</summary>
|
||||
/// <param name="input">The source string.</param>
|
||||
/// <param name="oldValue">The substring to find.</param>
|
||||
/// <param name="newValue">The replacement value.</param>
|
||||
/// <returns>A new string with the last occurrence replaced.</returns>
|
||||
public static string ReplaceLastOccurrence(this string input, string oldValue, string newValue)
|
||||
{
|
||||
int place = input.LastIndexOf(oldValue);
|
||||
return input.Remove(place, Math.Min(oldValue.Length, input.Length - place)).Insert(place, newValue);
|
||||
}
|
||||
|
||||
/// <summary>Counts the number of trailing whitespace characters in the string.</summary>
|
||||
/// <param name="input">The source string.</param>
|
||||
/// <returns>The number of whitespace characters at the end of the string.</returns>
|
||||
public static int WhiteSpaceAtEnd(this string input)
|
||||
{
|
||||
int count = 0;
|
||||
|
||||
Reference in New Issue
Block a user