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))