Improve Regex performance and change .NET version to .NET 7

This commit is contained in:
Stone_Red
2022-11-17 12:37:32 +01:00
parent e539813314
commit 0f7f63ae9a
8 changed files with 485 additions and 457 deletions
+157 -143
View File
@@ -2,177 +2,191 @@
using System.Linq;
using System.Text.RegularExpressions;
namespace YesNt.Interpreter.Utilities
namespace YesNt.Interpreter.Utilities;
internal static partial class Evaluator
{
internal static class Evaluator
public static bool? EvaluateCondition(string input)
{
public static bool? EvaluateCondition(string input)
if (input.ToLower().FromSaveString().Trim() == "true")
{
if (input.ToLower().FromSaveString().Trim() == "true")
{
return true;
}
else if (input.ToLower().FromSaveString().Trim() == "false")
{
return false;
}
return true;
}
else if (input.ToLower().FromSaveString().Trim() == "false")
{
return false;
}
string[] parts = input.Split("==");
if (parts.Length == 2)
{
string part1 = parts[0].FromSaveString().Trim();
string part2 = parts[1].FromSaveString().Trim();
return part1 == part2;
}
string[] parts = input.Split("==");
if (parts.Length == 2)
{
string part1 = parts[0].FromSaveString().Trim();
string part2 = parts[1].FromSaveString().Trim();
return part1 == part2;
}
parts = input.Split("!=");
if (parts.Length == 2)
{
string part1 = parts[0].FromSaveString().Trim();
string part2 = parts[1].FromSaveString().Trim();
return part1 != part2;
}
parts = input.Split("!=");
if (parts.Length == 2)
{
string part1 = parts[0].FromSaveString().Trim();
string part2 = parts[1].FromSaveString().Trim();
return part1 != part2;
}
parts = input.Split(">=");
if (parts.Length == 2)
{
bool succ1 = parts[0].ToStandardizedNumber(out double part1);
bool succ2 = parts[1].ToStandardizedNumber(out double part2);
return succ1 && succ2 && part1 >= part2;
}
parts = input.Split(">=");
if (parts.Length == 2)
{
bool succ1 = parts[0].ToStandardizedNumber(out double part1);
bool succ2 = parts[1].ToStandardizedNumber(out double part2);
return succ1 && succ2 && part1 >= part2;
}
parts = input.Split("<=");
if (parts.Length == 2)
{
bool succ1 = parts[0].ToStandardizedNumber(out double part1);
bool succ2 = parts[1].ToStandardizedNumber(out double part2);
return succ1 && succ2 && part1 <= part2;
}
parts = input.Split("<=");
if (parts.Length == 2)
{
bool succ1 = parts[0].ToStandardizedNumber(out double part1);
bool succ2 = parts[1].ToStandardizedNumber(out double part2);
return succ1 && succ2 && part1 <= part2;
}
parts = input.Split(">");
if (parts.Length == 2)
{
bool succ1 = parts[0].ToStandardizedNumber(out double part1);
bool succ2 = parts[1].ToStandardizedNumber(out double part2);
return succ1 && succ2 && part1 > part2;
}
parts = input.Split(">");
if (parts.Length == 2)
{
bool succ1 = parts[0].ToStandardizedNumber(out double part1);
bool succ2 = parts[1].ToStandardizedNumber(out double part2);
return succ1 && succ2 && part1 > part2;
}
parts = input.Split("<");
if (parts.Length == 2)
{
bool succ1 = parts[0].ToStandardizedNumber(out double part1);
bool succ2 = parts[1].ToStandardizedNumber(out double part2);
return succ1 && succ2 && part1 < part2;
}
parts = input.Split("<");
if (parts.Length == 2)
{
bool succ1 = parts[0].ToStandardizedNumber(out double part1);
bool succ2 = parts[1].ToStandardizedNumber(out double part2);
return succ1 && succ2 && part1 < part2;
}
return null;
}
public static string Calculate(string input)
{
input = PlusPlusRegex().Replace(input, "+");
input = MinusMinusRegex().Replace(input, "+");
input = MinusPlusRegex().Replace(input, "-");
input = PlusMinusRegex().Replace(input, "-");
string yes = Calculate(input, '+');
return yes;
}
private static string Calculate(string input, char op)
{
if (input is null)
{
return null;
}
public static string Calculate(string input)
{
input = Regex.Replace(input, @"(\+ +\+)+", "+");
input = Regex.Replace(input, @"(\- +\-)+", "+");
input = Regex.Replace(input, @"(\- +\+)+", "-");
input = Regex.Replace(input, @"(\+ +\-)+", "-");
input = input.FromSaveString();
string yes = Calculate(input, '+');
return yes;
MatchCollection matches = ParenthesesRegex().Matches(input);
while (matches.Count > 0)
{
for (int i = 0; i < matches.Count; i++)
{
string calc = matches[i].Value.Substring(1, matches[i].Length - 2);
string ret = Calculate(calc);
input = input.Replace(matches[i].Value, ret);
}
matches = ParenthesesRegex().Matches(input);
}
private static string Calculate(string input, char op)
string[] parts = input.Split(op);
//Weird fix
if (parts.Length >= 2 && string.IsNullOrWhiteSpace(parts[0]))
{
if (input is null)
parts[1] = $"{op}{parts[1]}";
parts = parts.Skip(1).ToArray();
}
double number = double.NaN;
foreach (string p in parts)
{
string part = p;
part = op switch
{
'+' => Calculate(part, '-'),
'-' => Calculate(part, '*'),
'*' => Calculate(part, '/'),
'/' => Calculate(part, '%'),
'%' => Calculate(part, '^'),
_ => part
};
if (part is null)
{
return null;
}
input = input.FromSaveString();
MatchCollection matches = Regex.Matches(input, @"\(([^()]+)\)");
while (matches.Count > 0)
if (part.ToStandardizedNumber(out double num))
{
for (int i = 0; i < matches.Count; i++)
if (double.IsNaN(number))
{
string calc = matches[i].Value.Substring(1, matches[i].Length - 2);
string ret = Calculate(calc);
input = input.Replace(matches[i].Value, ret);
}
matches = Regex.Matches(input, @"\(([^()]+)\)");
}
string[] parts = input.Split(op);
//Weird fix
if (parts.Length >= 2 && string.IsNullOrWhiteSpace(parts[0]))
{
parts[1] = $"{op}{parts[1]}";
parts = parts.Skip(1).ToArray();
}
double number = double.NaN;
foreach (string p in parts)
{
string part = p;
part = op switch
{
'+' => Calculate(part, '-'),
'-' => Calculate(part, '*'),
'*' => Calculate(part, '/'),
'/' => Calculate(part, '%'),
'%' => Calculate(part, '^'),
_ => part
};
if (part is null)
{
return null;
}
if (part.ToStandardizedNumber(out double num))
{
if (double.IsNaN(number))
{
number = num;
}
else
{
switch (op)
{
case '+':
number += num;
break;
case '-':
number -= num;
break;
case '*':
number *= num;
break;
case '/':
number /= num;
break;
case '%':
number %= num;
break;
case '^':
number = Math.Pow(number, num);
break;
}
}
number = num;
}
else
{
return null;
switch (op)
{
case '+':
number += num;
break;
case '-':
number -= num;
break;
case '*':
number *= num;
break;
case '/':
number /= num;
break;
case '%':
number %= num;
break;
case '^':
number = Math.Pow(number, num);
break;
}
}
}
return number.ToString(System.Globalization.CultureInfo.InvariantCulture);
else
{
return null;
}
}
return number.ToString(System.Globalization.CultureInfo.InvariantCulture);
}
[GeneratedRegex("\\(([^()]+)\\)")]
private static partial Regex ParenthesesRegex();
[GeneratedRegex("(\\+ +\\+)+")]
private static partial Regex PlusPlusRegex();
[GeneratedRegex("(\\- +\\-)+")]
private static partial Regex MinusMinusRegex();
[GeneratedRegex("(\\- +\\+)+")]
private static partial Regex MinusPlusRegex();
[GeneratedRegex("(\\+ +\\-)+")]
private static partial Regex PlusMinusRegex();
}
+6 -6
View File
@@ -23,14 +23,14 @@ namespace YesNt.Interpreter.Utilities
public new void BeginOutputReadLine()
{
Stream baseStream = StandardOutput.BaseStream;
output = new AsyncStreamReader(this, baseStream, new UserCallBack(FixedOutputReadNotifyUser), StandardOutput.CurrentEncoding);
output = new AsyncStreamReader(baseStream, new UserCallBack(FixedOutputReadNotifyUser), StandardOutput.CurrentEncoding);
output.BeginReadLine();
}
public new void BeginErrorReadLine()
{
Stream baseStream = StandardError.BaseStream;
error = new AsyncStreamReader(this, baseStream, new UserCallBack(FixedErrorReadNotifyUser), StandardError.CurrentEncoding);
error = new AsyncStreamReader(baseStream, new UserCallBack(FixedErrorReadNotifyUser), StandardError.CurrentEncoding);
error.BeginReadLine();
}
@@ -90,17 +90,17 @@ namespace YesNt.Interpreter.Utilities
public virtual Encoding CurrentEncoding => encoding;
public virtual Stream BaseStream => stream;
internal AsyncStreamReader(Process process, Stream stream, UserCallBack callback, Encoding encoding) : this(process, stream, callback, encoding, 1024)
internal AsyncStreamReader(Stream stream, UserCallBack callback, Encoding encoding) : this(stream, callback, encoding, 1024)
{
}
internal AsyncStreamReader(Process process, Stream stream, UserCallBack callback, Encoding encoding, int bufferSize)
internal AsyncStreamReader(Stream stream, UserCallBack callback, Encoding encoding, int bufferSize)
{
Init(process, stream, callback, encoding, bufferSize);
Init(stream, callback, encoding, bufferSize);
messageQueue = new Queue();
}
private void Init(Process process, Stream stream, UserCallBack callback, Encoding encoding, int bufferSize)
private void Init(Stream stream, UserCallBack callback, Encoding encoding, int bufferSize)
{
this.stream = stream;
this.encoding = encoding;