Skip to content

Commit

Permalink
Add CultureInfo as a constructor parameter for specifying parsing cul…
Browse files Browse the repository at this point in the history
…ture.
  • Loading branch information
Giorgi committed Sep 30, 2015
1 parent f463ceb commit a6b6f1d
Show file tree
Hide file tree
Showing 2 changed files with 25 additions and 8 deletions.
9 changes: 5 additions & 4 deletions SimpleExpressionEvaluator.Tests/ExpressionEvaluatorTests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -167,12 +167,13 @@ public void Can_ParseNumbers_InDifferentCulture()
var clone = (CultureInfo)Thread.CurrentThread.CurrentCulture.Clone();
clone.NumberFormat.NumberDecimalSeparator = ",";
clone.NumberFormat.NumberGroupSeparator = " ";
Thread.CurrentThread.CurrentCulture = clone;

Assert.That(engine.Evaluate("5,67"), Is.EqualTo(5.67));
Assert.That(engine.Evaluate("5 000"), Is.EqualTo(5000));
var engineWithCulture = new ExpressionEvaluator(clone);

Assert.That(engine.Evaluate("5 000,67"), Is.EqualTo(5000.67));
Assert.That(engineWithCulture.Evaluate("5,67"), Is.EqualTo(5.67));
Assert.That(engineWithCulture.Evaluate("5 000"), Is.EqualTo(5000));

Assert.That(engineWithCulture.Evaluate("5 000,67"), Is.EqualTo(5000.67));
}

[Test]
Expand Down
24 changes: 20 additions & 4 deletions SimpleExpressionEvaluator/ExpressionEvaluator.cs
Original file line number Diff line number Diff line change
Expand Up @@ -11,10 +11,26 @@ namespace SimpleExpressionEvaluator
{
public class ExpressionEvaluator : DynamicObject
{
public CultureInfo Culture { get; set; }
private readonly Stack<Expression> expressionStack = new Stack<Expression>();
private readonly Stack<Symbol> operatorStack = new Stack<Symbol>();
private readonly List<string> parameters = new List<string>();

/// <summary>
/// Initializes new instance of <see cref="ExpressionEvaluator"></see> using <see cref="CultureInfo.InvariantCulture" />
/// </summary>
public ExpressionEvaluator() : this(CultureInfo.InvariantCulture)
{
}

/// <summary>
/// Initializes new instance of <see cref="ExpressionEvaluator"></see> using specified culture info
/// </summary>
/// <param name="culture">Culture to use for parsing decimal numbers</param>
public ExpressionEvaluator(CultureInfo culture)
{
Culture = culture;
}

public Func<object, decimal> Compile(string expression)
{
Expand Down Expand Up @@ -230,6 +246,9 @@ private void EvaluateWhile(Func<bool> condition)

private Expression ReadOperand(TextReader reader)
{
var decimalSeparator = Culture.NumberFormat.NumberDecimalSeparator[0];
var groupSeparator = Culture.NumberFormat.NumberGroupSeparator[0];

var operand = string.Empty;

int peek;
Expand All @@ -238,9 +257,6 @@ private Expression ReadOperand(TextReader reader)
{
var next = (char)peek;

var decimalSeparator = CultureInfo.CurrentCulture.NumberFormat.NumberDecimalSeparator[0];
var groupSeparator = CultureInfo.CurrentCulture.NumberFormat.NumberGroupSeparator[0];

if (char.IsDigit(next) || next == decimalSeparator || next == groupSeparator)
{
reader.Read();
Expand All @@ -252,7 +268,7 @@ private Expression ReadOperand(TextReader reader)
}
}

return Expression.Constant(decimal.Parse(operand));
return Expression.Constant(decimal.Parse(operand, Culture));
}

private Operation ReadOperation(TextReader reader)
Expand Down

0 comments on commit a6b6f1d

Please sign in to comment.