Initial commit

This commit is contained in:
github-classroom[bot] 2025-06-03 15:18:01 +00:00 committed by GitHub
commit 4b1294b32d
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
23 changed files with 5134 additions and 0 deletions

View file

@ -0,0 +1,38 @@
namespace MathInterpreter.Core;
/// <summary>
/// Collection of constants used throughout the project
/// </summary>
public static class Const
{
/// <summary>
/// The plus (+) character used both as sign and operator
/// </summary>
public const char PlusSign = '+';
/// <summary>
/// The minus (-) character used both as sign and operator
/// </summary>
public const char MinusSign = '-';
/// <summary>
/// The times (*) character used as operator
/// </summary>
public const char TimesSign = '*';
/// <summary>
/// The division (/) character used as operator
/// </summary>
public const char DivSign = '/';
/// <summary>
/// The decimal separator (.) character used in numbers to separate the integral from the fractional part
/// </summary>
public const char DecimalSeparator = '.';
/// <summary>
/// An error message used when a part of the code is reached that should never be reached due to
/// previous, proper validation
/// </summary>
public const string ImpossibleErrorMessage = "If validation works as intended, this should never happen";
}

View file

@ -0,0 +1,5 @@
using System;
namespace MathInterpreter.Core;
// TODO implement all exception classes

View file

@ -0,0 +1,47 @@
using System;
namespace MathInterpreter.Core;
/// <summary>
/// Provides utility methods for scanning character streams for certain parts of a maths expression
/// </summary>
public static class ExpressionScanner
{
/// <summary>
/// Scans the given expression for an operator (+, -, *, /)
/// </summary>
/// <param name="expression">Expression to process</param>
/// <returns>A scan result containing the operator found and the remaining part of the expression</returns>
/// <exception cref="OperatorException">Thrown if none or an unknown operator is found</exception>
public static ScanResult<Operator> ScanOperator(ReadOnlySpan<char> expression)
{
// TODO
throw new NotImplementedException();
}
/// <summary>
/// Scans the given expression for an operand which is a number which have to have an integral
/// part and may have a fractional part. It may also have a sign (+, -) in front of it.
/// </summary>
/// <param name="expression">Expression to process</param>
/// <returns>A scan result containing the parsed number and the remaining part expression</returns>
/// <exception cref="ExpressionFormatException">Thrown if a problem with the format of the number is found</exception>
public static ScanResult<double> ScanOperand(ReadOnlySpan<char> expression)
{
// TODO
throw new NotImplementedException();
}
/// <summary>
/// Scans the given expression for a whole number which may have a sign (+, -) in front of it
/// </summary>
/// <param name="expression">Expression to process</param>
/// <param name="allowSign">Flag indicating if a pre-fix sign (+, -) is allowed or not</param>
/// <returns>A scan result containing the parsed number and the remaining part expression</returns>
/// <exception cref="NumberFormatException">Thrown if no or an invalid number is found</exception>
public static ScanResult<int> ScanNumber(ReadOnlySpan<char> expression, bool allowSign)
{
// TODO
throw new NotImplementedException();
}
}

View file

@ -0,0 +1,67 @@
using System;
using System.Diagnostics;
namespace MathInterpreter.Core;
/// <summary>
/// Represents a mathematical expression
/// </summary>
public sealed class MathExpression
{
// TODO
/*
private double? _leftOperand;
private Operator? _operator;
private double? _result;
private double? _rightOperand;
*/
/// <summary>
/// Creates a new instance of <see cref="MathExpression" /> from the provided expression string.
/// Validates the provided expression and throws an exception if it is invalid.
/// </summary>
/// <param name="expressionString">The expression as a string</param>
/// <exception cref="OperatorException">Thrown if a problem with the operator is found</exception>
/// <exception cref="ExpressionFormatException">Thrown if a problem with the expression format is found</exception>
/// <exception cref="NumberValueException">Thrown if a problem with the value of a number is found</exception>
public MathExpression(string expressionString)
{
ValidateAndParse(expressionString.Trim().AsSpan());
}
/// <summary>
/// Gets the calculated result of the expression
/// </summary>
/// <exception cref="UnreachableException">
/// Thrown if validation during construction did not guard against an unexpected, invalid expression
/// </exception>
public double Result
{
get
{
// TODO
throw new NotImplementedException();
}
}
/// <summary>
/// Returns a string representation of the expression - this is not the originally provided string
/// but the cleaned up version
/// </summary>
/// <returns>String representation of the expression</returns>
/// <exception cref="UnreachableException">
/// Thrown if validation during construction did not guard against an unexpected, invalid expression
/// and left this instance in an invalid state
/// </exception>
public override string ToString()
{
// TODO
throw new NotImplementedException();
}
private void ValidateAndParse(ReadOnlySpan<char> expression)
{
// TODO
throw new NotImplementedException();
}
}

View file

@ -0,0 +1,12 @@
namespace MathInterpreter.Core;
/// <summary>
/// Possible operators in an expression
/// </summary>
public enum Operator
{
Plus,
Minus,
Multiply,
Divide
}

View file

@ -0,0 +1,40 @@
using System;
namespace MathInterpreter.Core;
/// <summary>
/// Result object of scan operations
/// </summary>
/// <typeparam name="T">Type of the parsed value</typeparam>
public readonly ref struct ScanResult<T> where T : struct
{
/// <summary>
/// Creates a new scan result based on a successfully parsed value - if parsing failed an Exception
/// would have been thrown and this constructor would not be called
/// </summary>
/// <param name="value">Parsed value</param>
/// <param name="length">Number of characters (digits) of the parsed value</param>
/// <param name="remainingExpression">Remaining part of the expression after extracting and parsing the value</param>
/// <exception cref="ArgumentOutOfRangeException">Thrown if an invalid argument is provided</exception>
public ScanResult(T value, int length, ReadOnlySpan<char> remainingExpression)
{
Value = value;
Length = -1; // TODO
RemainingExpression = remainingExpression;
}
/// <summary>
/// Gets the parsed value
/// </summary>
public T Value { get; }
/// <summary>
/// Gets the number of characters (digits) of the parsed value
/// </summary>
public int Length { get; }
/// <summary>
/// Gets the remaining part of the expression after extracting and parsing the value
/// </summary>
public ReadOnlySpan<char> RemainingExpression { get; }
}