Skip to content

Commit 0cf073c

Browse files
committed
Documentation
1 parent c00d592 commit 0cf073c

19 files changed

+190
-112
lines changed

StringMath.Tests/OptimizerTests.cs

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -27,10 +27,10 @@ public void Optimize(string input, string expected)
2727
{
2828
ITokenizer tokenizer = new Tokenizer(input);
2929
IParser parser = new Parser(tokenizer, _context);
30-
IExpressionVisitor<Expression> optimizer = new ExpressionOptimizer(_context);
30+
IExpressionVisitor<IExpression> optimizer = new ExpressionOptimizer(_context);
3131

32-
Expression parsedExpr = parser.Parse();
33-
Expression optimizedExpr = optimizer.Visit(parsedExpr);
32+
IExpression parsedExpr = parser.Parse();
33+
IExpression optimizedExpr = optimizer.Visit(parsedExpr);
3434
string actual = optimizedExpr.ToString();
3535

3636
Assert.AreEqual(expected, actual);
@@ -45,10 +45,10 @@ public void Optimize_Fails(string input, string expected)
4545
{
4646
ITokenizer tokenizer = new Tokenizer(input);
4747
IParser parser = new Parser(tokenizer, _context);
48-
IExpressionVisitor<Expression> optimizer = new ExpressionOptimizer(_context);
48+
IExpressionVisitor<IExpression> optimizer = new ExpressionOptimizer(_context);
4949

50-
Expression parsedExpr = parser.Parse();
51-
Expression optimizedExpr = optimizer.Visit(parsedExpr);
50+
IExpression parsedExpr = parser.Parse();
51+
IExpression optimizedExpr = optimizer.Visit(parsedExpr);
5252
string actual = optimizedExpr.ToString();
5353

5454
Assert.AreNotEqual(expected, actual);

StringMath.Tests/ParserTests.cs

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -27,7 +27,7 @@ public void ParseMathExpression(string input, string expected)
2727
ITokenizer tokenizer = new Tokenizer(input);
2828
IParser parser = new Parser(tokenizer, _context);
2929

30-
Expression result = parser.Parse();
30+
IExpression result = parser.Parse();
3131
string actual = result.ToString();
3232

3333
Assert.AreEqual(expected, actual);
@@ -94,7 +94,7 @@ public void ParseExpression_CustomOperators(string input, string expected)
9494
ITokenizer tokenizer = new Tokenizer(input);
9595
IParser parser = new Parser(tokenizer, context);
9696

97-
Expression result = parser.Parse();
97+
IExpression result = parser.Parse();
9898
string actual = result.ToString();
9999

100100
Assert.AreEqual(expected, actual);
@@ -129,7 +129,7 @@ public void ParseVariableExpression(string expected, string name)
129129
ITokenizer tokenizer = new Tokenizer(expected);
130130
IParser parser = new Parser(tokenizer, _context);
131131

132-
Expression result = parser.Parse();
132+
IExpression result = parser.Parse();
133133
string actual = result.ToString();
134134

135135
Assert.IsInstanceOf<VariableExpression>(result);
@@ -169,7 +169,7 @@ public void ParseBinaryExpression(string input, string expected)
169169
ITokenizer tokenizer = new Tokenizer(input);
170170
IParser parser = new Parser(tokenizer, _context);
171171

172-
Expression result = parser.Parse();
172+
IExpression result = parser.Parse();
173173
string actual = result.ToString();
174174

175175
Assert.IsInstanceOf<BinaryExpression>(result);
@@ -193,7 +193,7 @@ public void ParseUnaryExpression(string input, string expected)
193193
ITokenizer tokenizer = new Tokenizer(input);
194194
IParser parser = new Parser(tokenizer, _context);
195195

196-
Expression result = parser.Parse();
196+
IExpression result = parser.Parse();
197197
string actual = result.ToString();
198198

199199
Assert.IsInstanceOf<UnaryExpression>(result);
@@ -223,7 +223,7 @@ public void ParseConstantExpression(string expected)
223223
ITokenizer tokenizer = new Tokenizer(expected);
224224
IParser parser = new Parser(tokenizer, _context);
225225

226-
Expression result = parser.Parse();
226+
IExpression result = parser.Parse();
227227
string actual = result.ToString();
228228

229229
Assert.IsInstanceOf<ConstantExpression>(result);
@@ -260,7 +260,7 @@ public void ParseGroupingExpression(string expected)
260260
ITokenizer tokenizer = new Tokenizer(expected);
261261
IParser parser = new Parser(tokenizer, _context);
262262

263-
Expression result = parser.Parse();
263+
IExpression result = parser.Parse();
264264
string actual = result.ToString();
265265

266266
Assert.IsInstanceOf<GroupingExpression>(result);

StringMath/Evaluator/Calculator.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@
33
namespace StringMath
44
{
55
/// <inheritdoc />
6-
public class Calculator : VariablesCollection, ICalculator
6+
public sealed class Calculator : VariablesCollection, ICalculator
77
{
88
private readonly IMathContext _mathContext;
99
private readonly IExpressionVisitor<ValueExpression> _evaluator;

StringMath/Evaluator/ExpressionEvaluator.cs

Lines changed: 13 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@ namespace StringMath
66
/// <inheritdoc />
77
internal sealed class ExpressionEvaluator : IExpressionVisitor<ValueExpression>
88
{
9-
private readonly Dictionary<Type, Func<Expression, ValueExpression>> _expressionEvaluators;
9+
private readonly Dictionary<ExpressionType, Func<IExpression, ValueExpression>> _expressionEvaluators;
1010
private readonly IMathContext _context;
1111
private readonly IVariablesCollection _variables;
1212

@@ -21,20 +21,20 @@ public ExpressionEvaluator(IMathContext context, IVariablesCollection variables)
2121
_variables = variables;
2222
_context = context;
2323

24-
_expressionEvaluators = new Dictionary<Type, Func<Expression, ValueExpression>>
24+
_expressionEvaluators = new Dictionary<ExpressionType, Func<IExpression, ValueExpression>>
2525
{
26-
[typeof(BinaryExpression)] = EvaluateBinaryExpression,
27-
[typeof(UnaryExpression)] = EvaluateUnaryExpression,
28-
[typeof(ConstantExpression)] = EvaluateConstantExpression,
29-
[typeof(GroupingExpression)] = EvaluateGroupingExpression,
30-
[typeof(VariableExpression)] = EvaluateVariableExpression
26+
[ExpressionType.BinaryExpression] = EvaluateBinaryExpression,
27+
[ExpressionType.UnaryExpression] = EvaluateUnaryExpression,
28+
[ExpressionType.ConstantExpression] = EvaluateConstantExpression,
29+
[ExpressionType.GroupingExpression] = EvaluateGroupingExpression,
30+
[ExpressionType.VariableExpression] = EvaluateVariableExpression
3131
};
3232
}
3333

3434
/// <summary>Evaluates an expression tree and returns the resulting value.</summary>
3535
/// <param name="expression">The expression to evaluate.</param>
3636
/// <returns>An value expression.</returns>
37-
public ValueExpression Visit(Expression expression)
37+
public ValueExpression Visit(IExpression expression)
3838
{
3939
if (expression is ValueExpression expected)
4040
{
@@ -45,21 +45,21 @@ public ValueExpression Visit(Expression expression)
4545
return result;
4646
}
4747

48-
private ValueExpression EvaluateConstantExpression(Expression expr)
48+
private ValueExpression EvaluateConstantExpression(IExpression expr)
4949
{
5050
ConstantExpression constantExpr = (ConstantExpression)expr;
5151
ValueExpression valueExpr = constantExpr.ToValueExpression();
5252
return valueExpr;
5353
}
5454

55-
private ValueExpression EvaluateGroupingExpression(Expression expr)
55+
private ValueExpression EvaluateGroupingExpression(IExpression expr)
5656
{
5757
GroupingExpression groupingExpr = (GroupingExpression)expr;
5858
ValueExpression innerExpr = Visit(groupingExpr.Inner);
5959
return innerExpr;
6060
}
6161

62-
private ValueExpression EvaluateUnaryExpression(Expression expr)
62+
private ValueExpression EvaluateUnaryExpression(IExpression expr)
6363
{
6464
UnaryExpression unaryExpr = (UnaryExpression)expr;
6565
ValueExpression valueExpr = Visit(unaryExpr.Operand);
@@ -68,7 +68,7 @@ private ValueExpression EvaluateUnaryExpression(Expression expr)
6868
return new ValueExpression(result);
6969
}
7070

71-
private ValueExpression EvaluateBinaryExpression(Expression expr)
71+
private ValueExpression EvaluateBinaryExpression(IExpression expr)
7272
{
7373
BinaryExpression binaryExpr = (BinaryExpression)expr;
7474
ValueExpression leftExpr = Visit(binaryExpr.Left);
@@ -78,7 +78,7 @@ private ValueExpression EvaluateBinaryExpression(Expression expr)
7878
return new ValueExpression(result);
7979
}
8080

81-
private ValueExpression EvaluateVariableExpression(Expression expr)
81+
private ValueExpression EvaluateVariableExpression(IExpression expr)
8282
{
8383
VariableExpression variableExpr = (VariableExpression)expr;
8484
return _variables.TryGetValue(variableExpr.Name, out double value)

StringMath/Evaluator/ExpressionOptimizer.cs

Lines changed: 20 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -4,9 +4,9 @@
44
namespace StringMath
55
{
66
/// <inheritdoc />
7-
internal class ExpressionOptimizer : IExpressionVisitor<Expression>
7+
internal class ExpressionOptimizer : IExpressionVisitor<IExpression>
88
{
9-
private readonly Dictionary<Type, Func<Expression, Expression>> _expressionOptimizers;
9+
private readonly Dictionary<ExpressionType, Func<IExpression, IExpression>> _expressionOptimizers;
1010
private readonly IMathContext _context;
1111

1212
/// <summary>Initializez a new instance of an expression optimizer.</summary>
@@ -16,43 +16,43 @@ public ExpressionOptimizer(IMathContext mathContext)
1616
mathContext.EnsureNotNull(nameof(mathContext));
1717
_context = mathContext;
1818

19-
_expressionOptimizers = new Dictionary<Type, Func<Expression, Expression>>
19+
_expressionOptimizers = new Dictionary<ExpressionType, Func<IExpression, IExpression>>
2020
{
21-
[typeof(BinaryExpression)] = OptimizeBinaryExpression,
22-
[typeof(UnaryExpression)] = EvaluateUnaryExpression,
23-
[typeof(ConstantExpression)] = OptimizeConstantExpression,
24-
[typeof(GroupingExpression)] = OptimizeGroupingExpression,
25-
[typeof(VariableExpression)] = SkipExpressionOptimization,
26-
[typeof(ValueExpression)] = SkipExpressionOptimization
21+
[ExpressionType.BinaryExpression] = OptimizeBinaryExpression,
22+
[ExpressionType.UnaryExpression] = EvaluateUnaryExpression,
23+
[ExpressionType.ConstantExpression] = OptimizeConstantExpression,
24+
[ExpressionType.GroupingExpression] = OptimizeGroupingExpression,
25+
[ExpressionType.VariableExpression] = SkipExpressionOptimization,
26+
[ExpressionType.ValueExpression] = SkipExpressionOptimization
2727
};
2828
}
2929

3030
/// <summary>Simplifies an expression tree by removing unnecessary nodes and evaluating constant expressions.</summary>
3131
/// <param name="expression">The expression tree to optimize.</param>
3232
/// <returns>An optimized expression tree.</returns>
33-
public Expression Visit(Expression expression)
33+
public IExpression Visit(IExpression expression)
3434
{
35-
Expression result = _expressionOptimizers[expression.Type](expression);
35+
IExpression result = _expressionOptimizers[expression.Type](expression);
3636
return result;
3737
}
3838

39-
private Expression OptimizeConstantExpression(Expression expr)
39+
private IExpression OptimizeConstantExpression(IExpression expr)
4040
{
4141
ConstantExpression constantExpr = (ConstantExpression)expr;
4242
return constantExpr.ToValueExpression();
4343
}
4444

45-
private Expression OptimizeGroupingExpression(Expression expr)
45+
private IExpression OptimizeGroupingExpression(IExpression expr)
4646
{
4747
GroupingExpression groupingExpr = (GroupingExpression)expr;
48-
Expression innerExpr = Visit(groupingExpr.Inner);
48+
IExpression innerExpr = Visit(groupingExpr.Inner);
4949
return innerExpr;
5050
}
5151

52-
private Expression EvaluateUnaryExpression(Expression expr)
52+
private IExpression EvaluateUnaryExpression(IExpression expr)
5353
{
5454
UnaryExpression unaryExpr = (UnaryExpression)expr;
55-
Expression operandExpr = Visit(unaryExpr.Operand);
55+
IExpression operandExpr = Visit(unaryExpr.Operand);
5656
if (operandExpr is ValueExpression valueExpr)
5757
{
5858
double result = _context.EvaluateUnary(unaryExpr.OperatorName, valueExpr.Value);
@@ -62,11 +62,11 @@ private Expression EvaluateUnaryExpression(Expression expr)
6262
return new UnaryExpression(unaryExpr.OperatorName, operandExpr);
6363
}
6464

65-
private Expression OptimizeBinaryExpression(Expression expr)
65+
private IExpression OptimizeBinaryExpression(IExpression expr)
6666
{
6767
BinaryExpression binaryExpr = (BinaryExpression)expr;
68-
Expression leftExpr = Visit(binaryExpr.Left);
69-
Expression rightExpr = Visit(binaryExpr.Right);
68+
IExpression leftExpr = Visit(binaryExpr.Left);
69+
IExpression rightExpr = Visit(binaryExpr.Right);
7070

7171
if (leftExpr is ValueExpression leftValue && rightExpr is ValueExpression rightValue)
7272
{
@@ -77,7 +77,7 @@ private Expression OptimizeBinaryExpression(Expression expr)
7777
return new BinaryExpression(leftExpr, binaryExpr.OperatorName, rightExpr);
7878
}
7979

80-
private Expression SkipExpressionOptimization(Expression expr)
80+
private IExpression SkipExpressionOptimization(IExpression expr)
8181
{
8282
return expr;
8383
}
Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,11 @@
11
namespace StringMath
22
{
33
/// <summary>Contract for expression visitors.</summary>
4-
internal interface IExpressionVisitor<T> where T : Expression
4+
internal interface IExpressionVisitor<out T> where T : IExpression
55
{
66
/// <summary>Visits an expression tree and transforms it to another of type <typeparamref name="T"/>.</summary>
77
/// <param name="expression">The expression to transform.</param>
88
/// <returns>An expression of type <typeparamref name="T"/>.</returns>
9-
T Visit(Expression expression);
9+
T Visit(IExpression expression);
1010
}
1111
}

StringMath/Evaluator/OperationInfo.cs

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -3,21 +3,21 @@
33
namespace StringMath
44
{
55
/// <summary>An optimized and cached math expression.</summary>
6-
public class OperationInfo
6+
public sealed class OperationInfo
77
{
88
/// <summary>Initializez a new instance of an operation info.</summary>
99
/// <param name="root">The optimized expression tree.</param>
1010
/// <param name="expression">The math expression string.</param>
1111
/// <param name="variables">A collection of variables extracted from the expression.</param>
12-
private OperationInfo(Expression root, string expression, IReadOnlyCollection<string> variables)
12+
private OperationInfo(IExpression root, string expression, IReadOnlyCollection<string> variables)
1313
{
1414
Root = root;
1515
Expression = expression;
1616
Variables = variables;
1717
}
1818

1919
/// <summary>The cached expression tree.</summary>
20-
internal Expression Root { get; }
20+
internal IExpression Root { get; }
2121

2222
/// <summary>The math expression that was used to create this operation.</summary>
2323
public string Expression { get; }
@@ -33,9 +33,9 @@ internal static OperationInfo Create(string expression, IMathContext context)
3333
{
3434
ITokenizer tokenizer = new Tokenizer(expression);
3535
IParser parser = new Parser(tokenizer, context);
36-
IExpressionVisitor<Expression> optimizer = new ExpressionOptimizer(context);
37-
Expression root = parser.Parse();
38-
Expression optimized = optimizer.Visit(root);
36+
IExpressionVisitor<IExpression> optimizer = new ExpressionOptimizer(context);
37+
IExpression root = parser.Parse();
38+
IExpression optimized = optimizer.Visit(root);
3939

4040
return new OperationInfo(optimized, expression, parser.Variables);
4141
}

StringMath/Parser/BinaryExpression.cs

Lines changed: 18 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -2,20 +2,33 @@
22

33
namespace StringMath
44
{
5-
internal sealed class BinaryExpression : Expression
5+
/// <summary>A binary expression.</summary>
6+
internal sealed class BinaryExpression : IExpression
67
{
7-
public BinaryExpression(Expression left, string operatorName, Expression right)
8+
/// <summary>Initializez a new instance of a binary expression.</summary>
9+
/// <param name="left">The left expression tree.</param>
10+
/// <param name="operatorName">The binary operator's name.</param>
11+
/// <param name="right">The right expression tree.</param>
12+
public BinaryExpression(IExpression left, string operatorName, IExpression right)
813
{
914
Left = left;
1015
OperatorName = operatorName;
1116
Right = right;
1217
}
1318

14-
public Expression Left { get; }
19+
/// <summary>The left expression tree.</summary>
20+
public IExpression Left { get; }
21+
22+
/// <summary>The binary operator's name.</summary>
1523
public string OperatorName { get; }
16-
public Expression Right { get; }
17-
public override Type Type => typeof(BinaryExpression);
1824

25+
/// <summary>The right expression tree.</summary>
26+
public IExpression Right { get; }
27+
28+
/// <inheritdoc />
29+
public ExpressionType Type => ExpressionType.BinaryExpression;
30+
31+
/// <inheritdoc />
1932
public override string ToString()
2033
{
2134
return $"{Left} {OperatorName} {Right}";

StringMath/Parser/ConstantExpression.cs

Lines changed: 10 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,15 +1,20 @@
1-
using System;
2-
3-
namespace StringMath
1+
namespace StringMath
42
{
5-
internal sealed class ConstantExpression : Expression
3+
/// <summary>A constant expression.</summary>
4+
internal sealed class ConstantExpression : IExpression
65
{
6+
/// <summary>Initializez a new instance of a constant expression.</summary>
7+
/// <param name="value">The value of the constant.</param>
78
public ConstantExpression(string value)
89
=> Value = value;
910

11+
/// <summary>The constant value.</summary>
1012
public string Value { get; }
11-
public override Type Type => typeof(ConstantExpression);
1213

14+
/// <inheritdoc />
15+
public ExpressionType Type => ExpressionType.ConstantExpression;
16+
17+
/// <inheritdoc />
1318
public override string ToString()
1419
{
1520
return Value;

0 commit comments

Comments
 (0)