From 4d6a0c6babe2541e446646774a1613d1dd65dd38 Mon Sep 17 00:00:00 2001 From: Jordan Wages Date: Wed, 24 Jun 2026 03:34:35 -0500 Subject: [PATCH] XMLDoc --- src/Core/InputInterpreter.cs | 109 +++++++++++++++++++++++++++++++---- 1 file changed, 98 insertions(+), 11 deletions(-) diff --git a/src/Core/InputInterpreter.cs b/src/Core/InputInterpreter.cs index b009bda..3690886 100644 --- a/src/Core/InputInterpreter.cs +++ b/src/Core/InputInterpreter.cs @@ -4,32 +4,47 @@ using System.IO; namespace CSMic { + /// The interpreter that parses user input at runtime into strongly typed .Net values. public class InputInterpreter { #region Members + /// The numeric value store. private decimal numericValue = 0; + /// The string value store. private string stringValue = string.Empty; + /// The time taken for the last entry the parser interpreted. private TimeSpan lastExecutionTime = TimeSpan.Zero; - // Variable stores + #region Variable stores + /// (Immutable) The numeric variables. private readonly Dictionary numericVariables; + /// (Immutable) The numeric array variables. private readonly Dictionary numericArrayVariables; - private readonly Dictionary expressionVariables; + /// (Immutable) The expression variables. + private readonly Dictionary expressionVariables; + #endregion - // Function registry + /// (Immutable) The function registry. private readonly Dictionary functions; - // Tracks expression variables currently being evaluated to prevent recursion + /// + /// (Immutable) Tracks expression variables currently being evaluated to prevent recursion. + /// private readonly List evaluationStack; - // Shared recursion tracker across nested evaluations - private sealed class RecursionTracker { public int Hits; } + /// Shared recursion tracker used across nested evaluations. + private sealed class RecursionTracker { + /// The number of recursive trips detected. + public int Hits; + } + /// (Immutable) The recursion tracker. private readonly RecursionTracker recursion; #endregion #region Constructors + /// Default constructor. public InputInterpreter() { numericVariables = new Dictionary(StringComparer.Ordinal); @@ -40,7 +55,8 @@ namespace CSMic recursion = new RecursionTracker(); } - // Internal constructor to create a child interpreter that shares stores + /// Internal constructor to create a child interpreter that shares stores. + /// The parent . internal InputInterpreter(InputInterpreter parent) { this.numericVariables = parent.numericVariables; @@ -57,6 +73,8 @@ namespace CSMic #region Properties + /// Gets the numeric value. + /// The numeric value. public decimal NumericValue { get @@ -65,6 +83,8 @@ namespace CSMic } } + /// Gets the string value. + /// The string value. public string StringValue { get @@ -73,6 +93,8 @@ namespace CSMic } } + /// Gets the last execution time. + /// The last execution time. public TimeSpan LastExecutionTime { get @@ -81,6 +103,8 @@ namespace CSMic } } + /// Gets the variables. + /// The encapsulated variables. public IEnumerable Variables { get @@ -95,12 +119,17 @@ namespace CSMic #region Output Plumbing + /// Hydrates long-lived output variables for delayed access. + /// The numeric value store. + /// The string value store. internal void ProduceOutput(decimal numericValue, string stringValue) { this.numericValue = numericValue; this.stringValue = stringValue; } + /// Hydrates long-lived output variables for delayed access. + /// The function value to be converted. internal void ProduceOutput(FunctionValue functionValue) { switch (functionValue.Type) @@ -126,12 +155,24 @@ namespace CSMic #region Variable APIs + /// Attempts to get a numeric value from the variable store with a given name. + /// The name. + /// [out] The value. + /// True if it succeeds, false if it fails. internal bool TryGetNumeric(string name, out decimal value) => numericVariables.TryGetValue(name, out value); + /// Attempts to get a numeric array from the variable store with a given name. + /// The name. + /// [out] The values. + /// True if it succeeds, false if it fails. internal bool TryGetNumericArray(string name, out decimal[] values) => numericArrayVariables.TryGetValue(name, out values!); + /// Attempts to get an expression from the variable store with a given name. + /// The name. + /// [out] The expression. + /// True if it succeeds, false if it fails. internal bool TryGetExpression(string name, out string expr) { if (expressionVariables.TryGetValue(name, out expr!)) @@ -142,9 +183,16 @@ namespace CSMic return false; } - // Recursion tracking helpers managed by the parser when evaluating expression variables + /// + /// Recursion tracking helpers managed by the parser when evaluating expression variables. + /// + /// The name of the variable to check. + /// True if currently evaluating, false if not. internal bool IsEvaluating(string name) => evaluationStack.Contains(name); + /// Begins evaluating a named expression. + /// The name of the expression variable. + /// The current recurrsion depth. internal int BeginEvaluating(string name) { int depth = evaluationStack.Count; @@ -152,6 +200,8 @@ namespace CSMic return depth; } + /// Ends evaluating a named expression. + /// The recurrsion depth. internal void EndEvaluating(int depth) { while (evaluationStack.Count > depth) @@ -160,46 +210,67 @@ namespace CSMic } } - // Recursion hit scoping across a single top-level expression evaluation + /// Recursion hit scoping across a single top-level expression evaluation. + /// An int. internal int BeginRecursionScope() { return recursion.Hits; } - // Returns true if recursion occurred within this scope + /// Returns true if recursion occurred within this scope. + /// The initial recurrsive hit counter. + /// True if recurrsion occurred within this scope, false otherwise. internal bool EndRecursionScope(int startHits) { return recursion.Hits > startHits; } + /// Mark a recursion hit. internal void MarkRecursionHit() { recursion.Hits++; } + /// Assign a numeric value to a variable. + /// The name of the variable. + /// [out] The value. internal void AssignNumeric(string name, decimal value) { numericVariables[name] = value; // Remove conflicting bindings expressionVariables.Remove(name); + numericArrayVariables.Remove(name); } + /// Assign a numeric array set to a variable. + /// The name of the variable. + /// [out] The array values. internal void AssignNumericArray(string name, decimal[] values) { numericArrayVariables[name] = values; + // Remove conflicting bindings + numericVariables.Remove(name); + expressionVariables.Remove(name); } + /// Assign an expression to a variable. + /// The name of the variable. + /// The expression text. internal void AssignExpression(string name, string expressionText) { expressionVariables[name] = expressionText; // Remove conflicting numeric value numericVariables.Remove(name); + numericArrayVariables.Remove(name); } #endregion #region Expression Evaluation + /// Evaluates an expression. + /// The expression text. + /// The result of the expression. internal FunctionValue EvaluateExpression(string expressionText) { // Create a child interpreter sharing stores, so ProduceOutput doesn't affect parent state @@ -221,7 +292,10 @@ namespace CSMic } } - // Primary developer-facing API: interpret input and return numeric result + /// Interpret input and return a numeric result. + /// The input text to parse. + /// A decimal value representing the immediate result. + /// This is the primary developer-facing API. public decimal Interpret(string input) { DateTime start = DateTime.Now; @@ -263,11 +337,24 @@ namespace CSMic #region Functions + /// Registers a function described by interface. + /// The function. + /// + /// + /// public void RegisterFunction(ICodedFunction function) { functions[function.Name] = function; } + /// Executes a named function. + /// The name. + /// A variable-length parameters list containing arguments. + /// The result of the function execution. + /// + /// + /// + /// internal FunctionValue ExecuteFunction(string name, params FunctionArgument[] args) { if (functions.TryGetValue(name, out var fn))