2020-09-10 05:01:30 +02:00
|
|
|
|
// Copyright (c) Microsoft Corporation
|
|
|
|
|
|
// The Microsoft Corporation licenses this file to you under the MIT license.
|
|
|
|
|
|
// See the LICENSE file in the project root for more information.
|
|
|
|
|
|
|
|
|
|
|
|
using System;
|
2021-01-19 18:04:15 +01:00
|
|
|
|
using System.Collections.Generic;
|
2020-09-10 05:01:30 +02:00
|
|
|
|
using System.Globalization;
|
|
|
|
|
|
using Mages.Core;
|
|
|
|
|
|
|
2021-01-20 11:38:52 +01:00
|
|
|
|
namespace Microsoft.PowerToys.Run.Plugin.Calculator
|
2020-09-10 05:01:30 +02:00
|
|
|
|
{
|
|
|
|
|
|
public class CalculateEngine
|
|
|
|
|
|
{
|
2021-01-19 18:04:15 +01:00
|
|
|
|
private readonly Engine _magesEngine = new Engine(new Configuration
|
|
|
|
|
|
{
|
|
|
|
|
|
Scope = new Dictionary<string, object>
|
|
|
|
|
|
{
|
|
|
|
|
|
{ "e", Math.E }, // e is not contained in the default mages engine
|
|
|
|
|
|
},
|
|
|
|
|
|
});
|
|
|
|
|
|
|
2020-09-10 05:01:30 +02:00
|
|
|
|
public const int RoundingDigits = 10;
|
|
|
|
|
|
|
|
|
|
|
|
public CalculateResult Interpret(string input)
|
|
|
|
|
|
{
|
2020-10-30 16:43:09 -07:00
|
|
|
|
// Using CurrentCulture this is user facing
|
2020-09-10 05:01:30 +02:00
|
|
|
|
return Interpret(input, CultureInfo.CurrentCulture);
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
public CalculateResult Interpret(string input, CultureInfo cultureInfo)
|
|
|
|
|
|
{
|
|
|
|
|
|
if (!CalculateHelper.InputValid(input))
|
|
|
|
|
|
{
|
|
|
|
|
|
return default;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
var result = _magesEngine.Interpret(input);
|
|
|
|
|
|
|
|
|
|
|
|
// This could happen for some incorrect queries, like pi(2)
|
|
|
|
|
|
if (result == null)
|
|
|
|
|
|
{
|
|
|
|
|
|
return default;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
result = TransformResult(result);
|
|
|
|
|
|
|
|
|
|
|
|
if (string.IsNullOrEmpty(result?.ToString()))
|
|
|
|
|
|
{
|
|
|
|
|
|
return default;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
var decimalResult = Convert.ToDecimal(result, cultureInfo);
|
2020-10-08 08:57:17 -07:00
|
|
|
|
var roundedResult = Round(decimalResult);
|
2020-09-10 05:01:30 +02:00
|
|
|
|
|
|
|
|
|
|
return new CalculateResult()
|
|
|
|
|
|
{
|
|
|
|
|
|
Result = decimalResult,
|
|
|
|
|
|
RoundedResult = roundedResult,
|
|
|
|
|
|
};
|
|
|
|
|
|
}
|
|
|
|
|
|
|
2020-10-08 08:57:17 -07:00
|
|
|
|
public static decimal Round(decimal value)
|
|
|
|
|
|
{
|
|
|
|
|
|
return Math.Round(value, RoundingDigits, MidpointRounding.AwayFromZero);
|
|
|
|
|
|
}
|
|
|
|
|
|
|
2020-09-10 05:01:30 +02:00
|
|
|
|
private static object TransformResult(object result)
|
|
|
|
|
|
{
|
|
|
|
|
|
if (result.ToString() == "NaN")
|
|
|
|
|
|
{
|
|
|
|
|
|
return Properties.Resources.wox_plugin_calculator_not_a_number;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
if (result is Function)
|
|
|
|
|
|
{
|
|
|
|
|
|
return Properties.Resources.wox_plugin_calculator_expression_not_complete;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
return result;
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|