Initial commit to new repository
This commit is contained in:
256
.decompiledproj/AxCopilot/Handlers/MathEvaluator.cs
Normal file
256
.decompiledproj/AxCopilot/Handlers/MathEvaluator.cs
Normal file
@@ -0,0 +1,256 @@
|
||||
using System;
|
||||
using System.Globalization;
|
||||
|
||||
namespace AxCopilot.Handlers;
|
||||
|
||||
internal static class MathEvaluator
|
||||
{
|
||||
private class Evaluator
|
||||
{
|
||||
private readonly string _s;
|
||||
|
||||
private int _i;
|
||||
|
||||
public Evaluator(string s)
|
||||
{
|
||||
_s = s;
|
||||
_i = 0;
|
||||
}
|
||||
|
||||
public double Parse()
|
||||
{
|
||||
double result = ParseExpr();
|
||||
if (_i < _s.Length)
|
||||
{
|
||||
throw new InvalidOperationException($"예기치 않은 문자: '{_s[_i]}'");
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
private double ParseExpr()
|
||||
{
|
||||
double num = ParseTerm();
|
||||
while (_i < _s.Length && (_s[_i] == '+' || _s[_i] == '-'))
|
||||
{
|
||||
char c = _s[_i++];
|
||||
double num2 = ParseTerm();
|
||||
num = ((c == '+') ? (num + num2) : (num - num2));
|
||||
}
|
||||
return num;
|
||||
}
|
||||
|
||||
private double ParseTerm()
|
||||
{
|
||||
double num = ParsePower();
|
||||
while (_i < _s.Length && (_s[_i] == '*' || _s[_i] == '/' || _s[_i] == '%'))
|
||||
{
|
||||
char c = _s[_i++];
|
||||
double num2 = ParsePower();
|
||||
num = c switch
|
||||
{
|
||||
'/' => num / num2,
|
||||
'*' => num * num2,
|
||||
_ => num % num2,
|
||||
};
|
||||
}
|
||||
return num;
|
||||
}
|
||||
|
||||
private double ParsePower()
|
||||
{
|
||||
double num = ParseUnary();
|
||||
if (_i < _s.Length && _s[_i] == '^')
|
||||
{
|
||||
_i++;
|
||||
double y = ParseUnary();
|
||||
return Math.Pow(num, y);
|
||||
}
|
||||
return num;
|
||||
}
|
||||
|
||||
private double ParseUnary()
|
||||
{
|
||||
if (_i < _s.Length && _s[_i] == '-')
|
||||
{
|
||||
_i++;
|
||||
return 0.0 - ParsePrimary();
|
||||
}
|
||||
if (_i < _s.Length && _s[_i] == '+')
|
||||
{
|
||||
_i++;
|
||||
return ParsePrimary();
|
||||
}
|
||||
return ParsePrimary();
|
||||
}
|
||||
|
||||
private double ParsePrimary()
|
||||
{
|
||||
if (_i >= _s.Length)
|
||||
{
|
||||
throw new InvalidOperationException("수식이 불완전합니다.");
|
||||
}
|
||||
if (_i + 1 < _s.Length && _s[_i] == '0' && _s[_i + 1] == 'x')
|
||||
{
|
||||
_i += 2;
|
||||
int i = _i;
|
||||
while (_i < _s.Length && "0123456789abcdef".Contains(_s[_i]))
|
||||
{
|
||||
_i++;
|
||||
}
|
||||
string s = _s;
|
||||
int num = i;
|
||||
return Convert.ToInt64(s.Substring(num, _i - num), 16);
|
||||
}
|
||||
if (char.IsDigit(_s[_i]) || _s[_i] == '.')
|
||||
{
|
||||
int i2 = _i;
|
||||
while (_i < _s.Length && (char.IsDigit(_s[_i]) || _s[_i] == '.'))
|
||||
{
|
||||
_i++;
|
||||
}
|
||||
if (_i < _s.Length && _s[_i] == 'e')
|
||||
{
|
||||
_i++;
|
||||
if (_i < _s.Length && (_s[_i] == '+' || _s[_i] == '-'))
|
||||
{
|
||||
_i++;
|
||||
}
|
||||
while (_i < _s.Length && char.IsDigit(_s[_i]))
|
||||
{
|
||||
_i++;
|
||||
}
|
||||
}
|
||||
string s2 = _s;
|
||||
int num = i2;
|
||||
return double.Parse(s2.Substring(num, _i - num), NumberStyles.Float, CultureInfo.InvariantCulture);
|
||||
}
|
||||
if (_s[_i] == '(')
|
||||
{
|
||||
_i++;
|
||||
double result = ParseExpr();
|
||||
if (_i < _s.Length && _s[_i] == ')')
|
||||
{
|
||||
_i++;
|
||||
}
|
||||
return result;
|
||||
}
|
||||
if (char.IsLetter(_s[_i]))
|
||||
{
|
||||
int i3 = _i;
|
||||
while (_i < _s.Length && (char.IsLetterOrDigit(_s[_i]) || _s[_i] == '_'))
|
||||
{
|
||||
_i++;
|
||||
}
|
||||
string s3 = _s;
|
||||
int num = i3;
|
||||
string text = s3.Substring(num, _i - num);
|
||||
switch (text)
|
||||
{
|
||||
case "pi":
|
||||
return Math.PI;
|
||||
case "e":
|
||||
return Math.E;
|
||||
case "inf":
|
||||
return double.PositiveInfinity;
|
||||
default:
|
||||
if (_i < _s.Length && _s[_i] == '(')
|
||||
{
|
||||
_i++;
|
||||
double num2 = ParseExpr();
|
||||
double? num3 = null;
|
||||
if (_i < _s.Length && _s[_i] == ',')
|
||||
{
|
||||
_i++;
|
||||
num3 = ParseExpr();
|
||||
}
|
||||
if (_i < _s.Length && _s[_i] == ')')
|
||||
{
|
||||
_i++;
|
||||
}
|
||||
if (1 == 0)
|
||||
{
|
||||
}
|
||||
double result2;
|
||||
switch (text)
|
||||
{
|
||||
case "sqrt":
|
||||
result2 = Math.Sqrt(num2);
|
||||
break;
|
||||
case "abs":
|
||||
result2 = Math.Abs(num2);
|
||||
break;
|
||||
case "ceil":
|
||||
result2 = Math.Ceiling(num2);
|
||||
break;
|
||||
case "floor":
|
||||
result2 = Math.Floor(num2);
|
||||
break;
|
||||
case "round":
|
||||
result2 = (num3.HasValue ? Math.Round(num2, (int)num3.Value) : Math.Round(num2));
|
||||
break;
|
||||
case "sin":
|
||||
result2 = Math.Sin(num2 * Math.PI / 180.0);
|
||||
break;
|
||||
case "cos":
|
||||
result2 = Math.Cos(num2 * Math.PI / 180.0);
|
||||
break;
|
||||
case "tan":
|
||||
result2 = Math.Tan(num2 * Math.PI / 180.0);
|
||||
break;
|
||||
case "asin":
|
||||
result2 = Math.Asin(num2) * 180.0 / Math.PI;
|
||||
break;
|
||||
case "acos":
|
||||
result2 = Math.Acos(num2) * 180.0 / Math.PI;
|
||||
break;
|
||||
case "atan":
|
||||
result2 = Math.Atan(num2) * 180.0 / Math.PI;
|
||||
break;
|
||||
case "log":
|
||||
result2 = (num3.HasValue ? Math.Log(num2, num3.Value) : Math.Log10(num2));
|
||||
break;
|
||||
case "log2":
|
||||
result2 = Math.Log2(num2);
|
||||
break;
|
||||
case "ln":
|
||||
result2 = Math.Log(num2);
|
||||
break;
|
||||
case "exp":
|
||||
result2 = Math.Exp(num2);
|
||||
break;
|
||||
case "pow":
|
||||
if (!num3.HasValue)
|
||||
{
|
||||
throw new InvalidOperationException("pow(x,y) 형식으로 사용하세요.");
|
||||
}
|
||||
result2 = Math.Pow(num2, num3.Value);
|
||||
break;
|
||||
case "min":
|
||||
result2 = (num3.HasValue ? Math.Min(num2, num3.Value) : num2);
|
||||
break;
|
||||
case "max":
|
||||
result2 = (num3.HasValue ? Math.Max(num2, num3.Value) : num2);
|
||||
break;
|
||||
default:
|
||||
throw new InvalidOperationException("알 수 없는 함수: " + text + "()");
|
||||
}
|
||||
if (1 == 0)
|
||||
{
|
||||
}
|
||||
return result2;
|
||||
}
|
||||
throw new InvalidOperationException("알 수 없는 식별자: " + text);
|
||||
}
|
||||
}
|
||||
throw new InvalidOperationException($"예기치 않은 문자: '{_s[_i]}'");
|
||||
}
|
||||
}
|
||||
|
||||
public static double Evaluate(string expr)
|
||||
{
|
||||
Evaluator evaluator = new Evaluator(expr.Replace(" ", "").Replace("×", "*").Replace("÷", "/")
|
||||
.Replace(",", ",")
|
||||
.ToLowerInvariant());
|
||||
return evaluator.Parse();
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user