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
+129 -115
View File
@@ -6,154 +6,168 @@ using YesNt.Interpreter.Enums;
using YesNt.Interpreter.Runtime; using YesNt.Interpreter.Runtime;
using YesNt.Interpreter.Utilities; using YesNt.Interpreter.Utilities;
namespace YesNt.CodeEditor namespace YesNt.CodeEditor;
internal partial class SyntaxHighlighter
{ {
internal class SyntaxHighlighter private readonly ReadOnlyCollection<StatementInformation> statementInformation;
public SyntaxHighlighter(ReadOnlyCollection<StatementInformation> statementInformation)
{ {
private readonly ReadOnlyCollection<StatementInformation> statementInformation; this.statementInformation = statementInformation;
}
public SyntaxHighlighter(ReadOnlyCollection<StatementInformation> statementInformation) public void Write(string input)
{
input = input.Replace("\0", string.Empty);
if (input.StartsWith('#'))
{ {
this.statementInformation = statementInformation; input = AddColorInformation(input, input, ConsoleColor.Gray, SearchMode.Exact);
} }
else
public void Write(string input)
{ {
input = input.Replace("\0", string.Empty); MatchCollection matches = EscapeSequenceRegex().Matches(input);
for (int i = 0; i < matches.Count; i++)
if (input.StartsWith('#'))
{ {
input = AddColorInformation(input, input, ConsoleColor.Gray, SearchMode.Exact); input = AddColorInformation(input, matches[i].Value, Console.ForegroundColor, SearchMode.Contains);
} }
else
foreach (StatementInformation statement in statementInformation)
{ {
MatchCollection matches = Regex.Matches(input, @"!!."); if (statement.IgnoreSyntaxHighlighting)
for (int i = 0; i < matches.Count; i++)
{ {
input = AddColorInformation(input, matches[i].Value, Console.ForegroundColor, SearchMode.Contains); continue;
} }
foreach (StatementInformation statement in statementInformation) string name = statement.SpaceAround switch
{ {
if (statement.IgnoreSyntaxHighlighting) SpaceAround.StartEnd => $" {statement.Name.Trim()} ",
SpaceAround.Start => $" {statement.Name.Trim()}",
SpaceAround.End => $"{statement.Name.Trim()} ",
_ => statement.Name
};
input = input.TrimEnd();
if (statement.SearchMode == SearchMode.StartOfLine && input.StartsWith(name))
{
if (statement.Seperator is not null && input.Contains(statement.Seperator))
{
input = AddColorInformation(input, statement.Seperator, statement.Color, SearchMode.StartOfLine);
}
else if (statement.Seperator is not null)
{ {
continue; continue;
} }
input = AddColorInformation(input, input[..name.Length], statement.Color, statement.SearchMode);
string name = statement.SpaceAround switch
{
SpaceAround.StartEnd => $" {statement.Name.Trim()} ",
SpaceAround.Start => $" {statement.Name.Trim()}",
SpaceAround.End => $"{statement.Name.Trim()} ",
_ => statement.Name
};
input = input.TrimEnd();
if (statement.SearchMode == SearchMode.StartOfLine && input.StartsWith(name))
{
if (statement.Seperator is not null && input.Contains(statement.Seperator))
{
input = AddColorInformation(input, statement.Seperator, statement.Color, SearchMode.StartOfLine);
}
else if (statement.Seperator is not null)
{
continue;
}
input = AddColorInformation(input, input[..name.Length], statement.Color, statement.SearchMode);
}
if (statement.SearchMode == SearchMode.Contains && $" {input} ".Contains(name))
{
if (statement.Seperator is not null && input.Contains(statement.Seperator))
{
input = AddColorInformation(input, statement.Seperator, statement.Color, SearchMode.StartOfLine);
}
else if (statement.Seperator is not null)
{
continue;
}
input = AddColorInformation($"{input} ", $"{input} ".Substring($"{input} ".IndexOf(name), name.Length), statement.Color, statement.SearchMode);
}
if (statement.SearchMode == SearchMode.EndOfLine && input.EndsWith(name))
{
if (statement.Seperator is not null && input.Contains(statement.Seperator))
{
input = AddColorInformation(input, statement.Seperator, statement.Color, SearchMode.StartOfLine);
}
else if (statement.Seperator is not null)
{
continue;
}
input = AddColorInformation(input, input[^name.Length..], statement.Color, statement.SearchMode);
}
if (statement.SearchMode == SearchMode.Exact && input.Equals(name))
{
if (statement.Seperator is not null && input.Contains(statement.Seperator))
{
input = AddColorInformation(input, statement.Seperator, statement.Color, SearchMode.StartOfLine);
}
else if (statement.Seperator is not null)
{
continue;
}
input = AddColorInformation(input, input, statement.Color, statement.SearchMode);
}
} }
if (statement.SearchMode == SearchMode.Contains && $" {input} ".Contains(name))
matches = Regex.Matches(input, @">[a-zA-Z0-9]+");
for (int i = 0; i < matches.Count; i++)
{ {
input = AddColorInformation(input, matches[i].Value, ConsoleColor.Cyan, SearchMode.Contains); if (statement.Seperator is not null && input.Contains(statement.Seperator))
{
input = AddColorInformation(input, statement.Seperator, statement.Color, SearchMode.StartOfLine);
}
else if (statement.Seperator is not null)
{
continue;
}
input = AddColorInformation($"{input} ", $"{input} ".Substring($"{input} ".IndexOf(name), name.Length), statement.Color, statement.SearchMode);
} }
if (statement.SearchMode == SearchMode.EndOfLine && input.EndsWith(name))
matches = Regex.Matches(input, @"^<[a-zA-Z0-9]+");
for (int i = 0; i < matches.Count; i++)
{ {
input = AddColorInformation(input, matches[i].Value, ConsoleColor.DarkCyan, SearchMode.StartOfLine); if (statement.Seperator is not null && input.Contains(statement.Seperator))
{
input = AddColorInformation(input, statement.Seperator, statement.Color, SearchMode.StartOfLine);
}
else if (statement.Seperator is not null)
{
continue;
}
input = AddColorInformation(input, input[^name.Length..], statement.Color, statement.SearchMode);
} }
if (statement.SearchMode == SearchMode.Exact && input.Equals(name))
matches = Regex.Matches(input, @"^!<[a-zA-Z0-9]+");
for (int i = 0; i < matches.Count; i++)
{ {
input = AddColorInformation(input, matches[i].Value, ConsoleColor.Blue, SearchMode.StartOfLine); if (statement.Seperator is not null && input.Contains(statement.Seperator))
{
input = AddColorInformation(input, statement.Seperator, statement.Color, SearchMode.StartOfLine);
}
else if (statement.Seperator is not null)
{
continue;
}
input = AddColorInformation(input, input, statement.Color, statement.SearchMode);
} }
} }
foreach (string part in input.Split("\0")) matches = VariableRegex().Matches(input);
for (int i = 0; i < matches.Count; i++)
{ {
ConsoleColor consoleColor; input = AddColorInformation(input, matches[i].Value, ConsoleColor.Cyan, SearchMode.Contains);
string messagePart = part; }
string stringColor = Regex.Match(messagePart, "(?<=(\\r))(.*)(?=\\r)").Value; matches = VariableDeclarationRegex().Matches(input);
bool succ = int.TryParse(stringColor, out int colorIndex); for (int i = 0; i < matches.Count; i++)
if (succ && colorIndex >= 0 && colorIndex < 16) {
{ input = AddColorInformation(input, matches[i].Value, ConsoleColor.DarkCyan, SearchMode.StartOfLine);
messagePart = messagePart.Replace($"\r{stringColor}\r", string.Empty); }
consoleColor = (ConsoleColor)colorIndex;
}
else
{
consoleColor = ConsoleColor.White;
}
if (consoleColor == Console.BackgroundColor) matches = GlobalVariableDeclarationRegex().Matches(input);
{ for (int i = 0; i < matches.Count; i++)
consoleColor = ConsoleColor.White; {
} input = AddColorInformation(input, matches[i].Value, ConsoleColor.Blue, SearchMode.StartOfLine);
Console.ForegroundColor = consoleColor;
Console.Write(messagePart);
} }
Console.ForegroundColor = ConsoleColor.Gray;
} }
private static string AddColorInformation(string originalString, string value, ConsoleColor color, SearchMode searchMode) foreach (string part in input.Split("\0"))
{ {
int spacesAtEnd = value.WhiteSpaceAtEnd(); ConsoleColor consoleColor;
string reult = searchMode switch string messagePart = part;
string stringColor = StringColorRegex().Match(messagePart).Value;
bool succ = int.TryParse(stringColor, out int colorIndex);
if (succ && colorIndex >= 0 && colorIndex < 16)
{ {
SearchMode.StartOfLine => originalString.ReplaceFirstOccurrence(value, $"\0\r{(int)color}\r{value.TrimEnd()}\0" + new string(' ', spacesAtEnd)), messagePart = messagePart.Replace($"\r{stringColor}\r", string.Empty);
SearchMode.EndOfLine => originalString.ReplaceLastOccurrence(value, $"\0\r{(int)color}\r{value.TrimEnd()}\0" + new string(' ', spacesAtEnd)), consoleColor = (ConsoleColor)colorIndex;
_ => originalString.Replace(value, $"\0\r{(int)color}\r{value.TrimEnd()}\0" + new string(' ', spacesAtEnd)) }
}; else
return reult; {
consoleColor = ConsoleColor.White;
}
if (consoleColor == Console.BackgroundColor)
{
consoleColor = ConsoleColor.White;
}
Console.ForegroundColor = consoleColor;
Console.Write(messagePart);
} }
Console.ForegroundColor = ConsoleColor.Gray;
} }
private static string AddColorInformation(string originalString, string value, ConsoleColor color, SearchMode searchMode)
{
int spacesAtEnd = value.WhiteSpaceAtEnd();
string reult = searchMode switch
{
SearchMode.StartOfLine => originalString.ReplaceFirstOccurrence(value, $"\0\r{(int)color}\r{value.TrimEnd()}\0" + new string(' ', spacesAtEnd)),
SearchMode.EndOfLine => originalString.ReplaceLastOccurrence(value, $"\0\r{(int)color}\r{value.TrimEnd()}\0" + new string(' ', spacesAtEnd)),
_ => originalString.Replace(value, $"\0\r{(int)color}\r{value.TrimEnd()}\0" + new string(' ', spacesAtEnd))
};
return reult;
}
[GeneratedRegex("!!.")]
private static partial Regex EscapeSequenceRegex();
[GeneratedRegex("^<[a-zA-Z0-9]+")]
private static partial Regex VariableDeclarationRegex();
[GeneratedRegex("^!<[a-zA-Z0-9]+")]
private static partial Regex GlobalVariableDeclarationRegex();
[GeneratedRegex(">[a-zA-Z0-9]+")]
private static partial Regex VariableRegex();
[GeneratedRegex("(?<=(\\r))(.*)(?=\\r)")]
private static partial Regex StringColorRegex();
} }
+1 -1
View File
@@ -2,7 +2,7 @@
<PropertyGroup> <PropertyGroup>
<OutputType>Exe</OutputType> <OutputType>Exe</OutputType>
<TargetFramework>net5.0</TargetFramework> <TargetFramework>net7.0</TargetFramework>
<Platforms>AnyCPU;x64</Platforms> <Platforms>AnyCPU;x64</Platforms>
</PropertyGroup> </PropertyGroup>
@@ -1,7 +1,7 @@
<Project Sdk="Microsoft.NET.Sdk"> <Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup> <PropertyGroup>
<TargetFramework>net6.0</TargetFramework> <TargetFramework>net7.0</TargetFramework>
<Nullable>enable</Nullable> <Nullable>enable</Nullable>
<IsPackable>false</IsPackable> <IsPackable>false</IsPackable>
@@ -9,112 +9,112 @@ using YesNt.Interpreter.Enums;
using YesNt.Interpreter.Runtime; using YesNt.Interpreter.Runtime;
using YesNt.Interpreter.Utilities; using YesNt.Interpreter.Utilities;
namespace YesNt.Interpreter.Statements namespace YesNt.Interpreter.Statements;
internal partial class ProcessingStatements : StatementRuntimeInformation
{ {
internal class ProcessingStatements : StatementRuntimeInformation [Statement("!calc", SearchMode.EndOfLine, SpaceAround.Start, ConsoleColor.DarkYellow, Priority = Priority.High)]
public void Calculate(string args)
{ {
private static readonly Regex calculationRegex = new Regex(@"[0-9*+().,^%/-]+[0-9*+ ().,^%/-]+[0-9*+().,^%/-]+"); MatchCollection matches = CalculationRegex().Matches(args.FromSaveString());
[Statement("!calc", SearchMode.EndOfLine, SpaceAround.Start, ConsoleColor.DarkYellow, Priority = Priority.High)] for (int i = 0; i < matches.Count; i++)
public void Calculate(string args)
{ {
MatchCollection matches = calculationRegex.Matches(args.FromSaveString()); string res = Evaluator.Calculate(matches[i].Value);
if (res is null)
for (int i = 0; i < matches.Count; i++)
{ {
string res = Evaluator.Calculate(matches[i].Value); RuntimeInfo.Exit("Invalid operation", true);
if (res is null) return;
}
args = args.FromSaveString().Replace(matches[i].Value, res);
}
RuntimeInfo.CurrentLine = args;
}
[Statement("!eval", SearchMode.EndOfLine, SpaceAround.Start, ConsoleColor.DarkYellow, Priority = Priority.VeryHigh)]
public void Evaluate(string args)
{
RuntimeInfo.CurrentLine = args.FromSaveString();
}
[Statement("!!", SearchMode.Contains, SpaceAround.None, ConsoleColor.DarkYellow, Priority = Priority.PreProcessing, KeepStatementInArgs = true)]
public void DontEvaluate(string args)
{
int index;
while ((index = args.IndexOf("!!")) != -1)
{
args = args.Remove(index, 2);
if (index < args.Length)
{
char charToEscape = args[index];
args = args.Remove(index, 1);
args = args.Insert(index, charToEscape.ToString().ToSaveString());
}
}
RuntimeInfo.CurrentLine = args;
}
[Statement("!task", SearchMode.EndOfLine, SpaceAround.Start, ConsoleColor.DarkYellow, Priority = Priority.VeryHigh)]
public void RunTask(string line)
{
int lineNumer = RuntimeInfo.LineNumber;
List<Line> lines = RuntimeInfo.Lines.GetRange(0, RuntimeInfo.Lines.Count);
Line oldLine = lines[lineNumer];
lines[lineNumer] = new Line(line, oldLine.FileName, oldLine.LineNumber);
_ = Task.Run(() =>
{
YesNtInterpreter interpreter = new YesNtInterpreter();
interpreter.Initialize();
interpreter.Execute(lines, RuntimeInfo.GloablVariables, lineNumer, RuntimeInfo);
});
RuntimeInfo.CurrentLine = string.Empty;
}
[Statement("slp", SearchMode.StartOfLine, SpaceAround.End, ConsoleColor.Magenta)]
public void Sleep(string args)
{
_ = int.TryParse(args, out int millisecondsTimeout);
ConsoleExtentions.Sleep(millisecondsTimeout, RuntimeInfo);
}
[Statement("imp", SearchMode.StartOfLine, SpaceAround.End, ConsoleColor.Magenta)]
public void Import(string path)
{
path = Path.Combine(RuntimeInfo.WorkingDirectory, path);
if (string.IsNullOrEmpty(Path.GetExtension(path)))
{
path = Path.ChangeExtension(path, "ynt");
}
if (File.Exists(path))
{
try
{
RuntimeInfo.Lines.RemoveAt(RuntimeInfo.LineNumber);
string[] lines = File.ReadAllLines(path);
for (int i = 0; i < lines.Length; i++)
{ {
RuntimeInfo.Exit("Invalid operation", true); RuntimeInfo.Lines.Insert(RuntimeInfo.LineNumber + i, new Line(lines[i], Path.GetFileName(path), i));
return;
} }
args = args.FromSaveString().Replace(matches[i].Value, res); RuntimeInfo.LineNumber--;
} }
catch
RuntimeInfo.CurrentLine = args;
}
[Statement("!eval", SearchMode.EndOfLine, SpaceAround.Start, ConsoleColor.DarkYellow, Priority = Priority.VeryHigh)]
public void Evaluate(string args)
{
RuntimeInfo.CurrentLine = args.FromSaveString();
}
[Statement("!!", SearchMode.Contains, SpaceAround.None, ConsoleColor.DarkYellow, Priority = Priority.PreProcessing, KeepStatementInArgs = true)]
public void DontEvaluate(string args)
{
int index;
while ((index = args.IndexOf("!!")) != -1)
{ {
args = args.Remove(index, 2); RuntimeInfo.Exit($"Could not load file \"{path}\"", true);
if (index < args.Length)
{
char charToEscape = args[index];
args = args.Remove(index, 1);
args = args.Insert(index, charToEscape.ToString().ToSaveString());
}
} }
RuntimeInfo.CurrentLine = args;
} }
else
[Statement("!task", SearchMode.EndOfLine, SpaceAround.Start, ConsoleColor.DarkYellow, Priority = Priority.VeryHigh)]
public void RunTask(string line)
{ {
int lineNumer = RuntimeInfo.LineNumber; RuntimeInfo.Exit($"Could not find file \"{path}\"", true);
List<Line> lines = RuntimeInfo.Lines.GetRange(0, RuntimeInfo.Lines.Count);
Line oldLine = lines[lineNumer];
lines[lineNumer] = new Line(line, oldLine.FileName, oldLine.LineNumber);
_ = Task.Run(() =>
{
YesNtInterpreter interpreter = new YesNtInterpreter();
interpreter.Initialize();
interpreter.Execute(lines, RuntimeInfo.GloablVariables, lineNumer, RuntimeInfo);
});
RuntimeInfo.CurrentLine = string.Empty;
}
[Statement("slp", SearchMode.StartOfLine, SpaceAround.End, ConsoleColor.Magenta)]
public void Sleep(string args)
{
_ = int.TryParse(args, out int millisecondsTimeout);
ConsoleExtentions.Sleep(millisecondsTimeout, RuntimeInfo);
}
[Statement("imp", SearchMode.StartOfLine, SpaceAround.End, ConsoleColor.Magenta)]
public void Import(string path)
{
path = Path.Combine(RuntimeInfo.WorkingDirectory, path);
if (string.IsNullOrEmpty(Path.GetExtension(path)))
{
path = Path.ChangeExtension(path, "ynt");
}
if (File.Exists(path))
{
try
{
RuntimeInfo.Lines.RemoveAt(RuntimeInfo.LineNumber);
string[] lines = File.ReadAllLines(path);
for (int i = 0; i < lines.Length; i++)
{
RuntimeInfo.Lines.Insert(RuntimeInfo.LineNumber + i, new Line(lines[i], Path.GetFileName(path), i));
}
RuntimeInfo.LineNumber--;
}
catch
{
RuntimeInfo.Exit($"Could not load file \"{path}\"", true);
}
}
else
{
RuntimeInfo.Exit($"Could not find file \"{path}\"", true);
}
} }
} }
[GeneratedRegex("[0-9*+().,^%/-]+[0-9*+ ().,^%/-]+[0-9*+().,^%/-]+")]
private static partial Regex CalculationRegex();
} }
@@ -5,119 +5,119 @@ using YesNt.Interpreter.Attributes;
using YesNt.Interpreter.Enums; using YesNt.Interpreter.Enums;
using YesNt.Interpreter.Runtime; using YesNt.Interpreter.Runtime;
namespace YesNt.Interpreter.Statements namespace YesNt.Interpreter.Statements;
internal partial class VariableStatements : StatementRuntimeInformation
{ {
internal class VariableStatements : StatementRuntimeInformation [Statement("<", SearchMode.StartOfLine, SpaceAround.None, Priority = Priority.VeryLow)]
public void DefineVariable(string args)
{ {
private static readonly Regex variableStatementRegex = new Regex(@">[a-zA-Z0-9]+"); string[] parts = args.Split('=');
if (parts.Length == 2)
[Statement("<", SearchMode.StartOfLine, SpaceAround.None, Priority = Priority.VeryLow)]
public void DefineVariable(string args)
{ {
string[] parts = args.Split('='); string key = parts[0].Trim();
if (parts.Length == 2) if (key.Contains(' '))
{ {
string key = parts[0].Trim(); RuntimeInfo.Exit("Invalid Syntax", true);
if (key.Contains(' '))
{
RuntimeInfo.Exit("Invalid Syntax", true);
}
if (RuntimeInfo.Variables.ContainsKey(key))
{
RuntimeInfo.Variables[key] = parts[1].Trim();
}
else
{
RuntimeInfo.Variables.Add(key, parts[1].Trim());
}
} }
else
{
RuntimeInfo.Exit("Invalid syntax", true);
}
}
[Statement("!<", SearchMode.StartOfLine, SpaceAround.None, Priority = Priority.VeryLow)]
public void DefineGlobalVariable(string args)
{
string[] parts = args.Split('=');
if (parts.Length == 2)
{
string key = parts[0].Trim();
if (key.Contains(' '))
{
RuntimeInfo.Exit("Invalid Syntax", true);
}
if (RuntimeInfo.GloablVariables.ContainsKey(key))
{
RuntimeInfo.GloablVariables[key] = parts[1].Trim();
}
else
{
RuntimeInfo.GloablVariables.Add(key, parts[1].Trim());
}
}
else
{
RuntimeInfo.Exit("Invalid syntax", true);
}
}
[Statement("del", SearchMode.StartOfLine, SpaceAround.End, System.ConsoleColor.Red, Priority = Priority.VeryLow)]
public void DeleteVariable(string args)
{
string key = args.Trim();
if (RuntimeInfo.Variables.ContainsKey(key)) if (RuntimeInfo.Variables.ContainsKey(key))
{ {
_ = RuntimeInfo.Variables.Remove(key); RuntimeInfo.Variables[key] = parts[1].Trim();
}
else if (RuntimeInfo.GloablVariables.ContainsKey(key))
{
_ = RuntimeInfo.GloablVariables.Remove(key);
} }
else else
{ {
RuntimeInfo.Exit($"Variable \"{key}\" not found", true); RuntimeInfo.Variables.Add(key, parts[1].Trim());
} }
} }
else
[Statement(">", SearchMode.Contains, SpaceAround.None, Priority = Priority.Highest)]
public void ReadVariable(string _)
{ {
if (!RuntimeInfo.CurrentLine.Contains('>')) RuntimeInfo.Exit("Invalid syntax", true);
}
}
[Statement("!<", SearchMode.StartOfLine, SpaceAround.None, Priority = Priority.VeryLow)]
public void DefineGlobalVariable(string args)
{
string[] parts = args.Split('=');
if (parts.Length == 2)
{
string key = parts[0].Trim();
if (key.Contains(' '))
{ {
RuntimeInfo.Exit("Invalid Syntax", true);
}
if (RuntimeInfo.GloablVariables.ContainsKey(key))
{
RuntimeInfo.GloablVariables[key] = parts[1].Trim();
}
else
{
RuntimeInfo.GloablVariables.Add(key, parts[1].Trim());
}
}
else
{
RuntimeInfo.Exit("Invalid syntax", true);
}
}
[Statement("del", SearchMode.StartOfLine, SpaceAround.End, System.ConsoleColor.Red, Priority = Priority.VeryLow)]
public void DeleteVariable(string args)
{
string key = args.Trim();
if (RuntimeInfo.Variables.ContainsKey(key))
{
_ = RuntimeInfo.Variables.Remove(key);
}
else if (RuntimeInfo.GloablVariables.ContainsKey(key))
{
_ = RuntimeInfo.GloablVariables.Remove(key);
}
else
{
RuntimeInfo.Exit($"Variable \"{key}\" not found", true);
}
}
[Statement(">", SearchMode.Contains, SpaceAround.None, Priority = Priority.Highest)]
public void ReadVariable(string _)
{
if (!RuntimeInfo.CurrentLine.Contains('>'))
{
return;
}
foreach (KeyValuePair<string, string> variable in RuntimeInfo.Variables)
{
RuntimeInfo.CurrentLine = RuntimeInfo.CurrentLine.Replace($">{variable.Key}", variable.Value);
}
foreach (KeyValuePair<string, string> variable in RuntimeInfo.GloablVariables)
{
RuntimeInfo.CurrentLine = RuntimeInfo.CurrentLine.Replace($">{variable.Key}", variable.Value);
}
if (RuntimeInfo.IsSearching)
{
return;
}
MatchCollection matches = VariableStatementRegex().Matches(RuntimeInfo.CurrentLine);
for (int i = 0; i < matches.Count; i++)
{
string varName = matches[i].Value.Replace(">", string.Empty);
if (!RuntimeInfo.Variables.ContainsKey(varName) && !RuntimeInfo.GloablVariables.ContainsKey(varName))
{
RuntimeInfo.Exit($"Variable \"{varName}\" not found", true);
return; return;
} }
foreach (KeyValuePair<string, string> variable in RuntimeInfo.Variables)
{
RuntimeInfo.CurrentLine = RuntimeInfo.CurrentLine.Replace($">{variable.Key}", variable.Value);
}
foreach (KeyValuePair<string, string> variable in RuntimeInfo.GloablVariables)
{
RuntimeInfo.CurrentLine = RuntimeInfo.CurrentLine.Replace($">{variable.Key}", variable.Value);
}
if (RuntimeInfo.IsSearching)
{
return;
}
MatchCollection matches = variableStatementRegex.Matches(RuntimeInfo.CurrentLine);
for (int i = 0; i < matches.Count; i++)
{
string varName = matches[i].Value.Replace(">", string.Empty);
if (!RuntimeInfo.Variables.ContainsKey(varName) && !RuntimeInfo.GloablVariables.ContainsKey(varName))
{
RuntimeInfo.Exit($"Variable \"{varName}\" not found", true);
return;
}
}
} }
} }
[GeneratedRegex(">[a-zA-Z0-9]+")]
private static partial Regex VariableStatementRegex();
} }
+157 -143
View File
@@ -2,177 +2,191 @@
using System.Linq; using System.Linq;
using System.Text.RegularExpressions; 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;
{ }
return true; else if (input.ToLower().FromSaveString().Trim() == "false")
} {
else if (input.ToLower().FromSaveString().Trim() == "false") return false;
{ }
return false;
}
string[] parts = input.Split("=="); string[] parts = input.Split("==");
if (parts.Length == 2) if (parts.Length == 2)
{ {
string part1 = parts[0].FromSaveString().Trim(); string part1 = parts[0].FromSaveString().Trim();
string part2 = parts[1].FromSaveString().Trim(); string part2 = parts[1].FromSaveString().Trim();
return part1 == part2; return part1 == part2;
} }
parts = input.Split("!="); parts = input.Split("!=");
if (parts.Length == 2) if (parts.Length == 2)
{ {
string part1 = parts[0].FromSaveString().Trim(); string part1 = parts[0].FromSaveString().Trim();
string part2 = parts[1].FromSaveString().Trim(); string part2 = parts[1].FromSaveString().Trim();
return part1 != part2; return part1 != part2;
} }
parts = input.Split(">="); parts = input.Split(">=");
if (parts.Length == 2) if (parts.Length == 2)
{ {
bool succ1 = parts[0].ToStandardizedNumber(out double part1); bool succ1 = parts[0].ToStandardizedNumber(out double part1);
bool succ2 = parts[1].ToStandardizedNumber(out double part2); bool succ2 = parts[1].ToStandardizedNumber(out double part2);
return succ1 && succ2 && part1 >= part2; return succ1 && succ2 && part1 >= part2;
} }
parts = input.Split("<="); parts = input.Split("<=");
if (parts.Length == 2) if (parts.Length == 2)
{ {
bool succ1 = parts[0].ToStandardizedNumber(out double part1); bool succ1 = parts[0].ToStandardizedNumber(out double part1);
bool succ2 = parts[1].ToStandardizedNumber(out double part2); bool succ2 = parts[1].ToStandardizedNumber(out double part2);
return succ1 && succ2 && part1 <= part2; return succ1 && succ2 && part1 <= part2;
} }
parts = input.Split(">"); parts = input.Split(">");
if (parts.Length == 2) if (parts.Length == 2)
{ {
bool succ1 = parts[0].ToStandardizedNumber(out double part1); bool succ1 = parts[0].ToStandardizedNumber(out double part1);
bool succ2 = parts[1].ToStandardizedNumber(out double part2); bool succ2 = parts[1].ToStandardizedNumber(out double part2);
return succ1 && succ2 && part1 > part2; return succ1 && succ2 && part1 > part2;
} }
parts = input.Split("<"); parts = input.Split("<");
if (parts.Length == 2) if (parts.Length == 2)
{ {
bool succ1 = parts[0].ToStandardizedNumber(out double part1); bool succ1 = parts[0].ToStandardizedNumber(out double part1);
bool succ2 = parts[1].ToStandardizedNumber(out double part2); bool succ2 = parts[1].ToStandardizedNumber(out double part2);
return succ1 && succ2 && part1 < 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; return null;
} }
public static string Calculate(string input) input = input.FromSaveString();
{
input = Regex.Replace(input, @"(\+ +\+)+", "+");
input = Regex.Replace(input, @"(\- +\-)+", "+");
input = Regex.Replace(input, @"(\- +\+)+", "-");
input = Regex.Replace(input, @"(\+ +\-)+", "-");
string yes = Calculate(input, '+'); MatchCollection matches = ParenthesesRegex().Matches(input);
return yes; 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; return null;
} }
input = input.FromSaveString(); if (part.ToStandardizedNumber(out double num))
MatchCollection matches = Regex.Matches(input, @"\(([^()]+)\)");
while (matches.Count > 0)
{ {
for (int i = 0; i < matches.Count; i++) if (double.IsNaN(number))
{ {
string calc = matches[i].Value.Substring(1, matches[i].Length - 2); number = num;
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;
}
}
} }
else 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;
}
} }
} }
else
return number.ToString(System.Globalization.CultureInfo.InvariantCulture); {
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() public new void BeginOutputReadLine()
{ {
Stream baseStream = StandardOutput.BaseStream; 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(); output.BeginReadLine();
} }
public new void BeginErrorReadLine() public new void BeginErrorReadLine()
{ {
Stream baseStream = StandardError.BaseStream; 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(); error.BeginReadLine();
} }
@@ -90,17 +90,17 @@ namespace YesNt.Interpreter.Utilities
public virtual Encoding CurrentEncoding => encoding; public virtual Encoding CurrentEncoding => encoding;
public virtual Stream BaseStream => stream; 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(); 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.stream = stream;
this.encoding = encoding; this.encoding = encoding;
+1 -1
View File
@@ -1,7 +1,7 @@
<Project Sdk="Microsoft.NET.Sdk"> <Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup> <PropertyGroup>
<TargetFramework>net5.0</TargetFramework> <TargetFramework>net7.0</TargetFramework>
<RootNamespace>YesNt.Interpreter</RootNamespace> <RootNamespace>YesNt.Interpreter</RootNamespace>
<ApplicationIcon /> <ApplicationIcon />
<OutputType>Exe</OutputType> <OutputType>Exe</OutputType>