diff --git a/YesNt.CodeEditor/SyntaxHighlighter.cs b/YesNt.CodeEditor/SyntaxHighlighter.cs index d85fc6b..b69420d 100644 --- a/YesNt.CodeEditor/SyntaxHighlighter.cs +++ b/YesNt.CodeEditor/SyntaxHighlighter.cs @@ -6,154 +6,168 @@ using YesNt.Interpreter.Enums; using YesNt.Interpreter.Runtime; using YesNt.Interpreter.Utilities; -namespace YesNt.CodeEditor +namespace YesNt.CodeEditor; + +internal partial class SyntaxHighlighter { - internal class SyntaxHighlighter + private readonly ReadOnlyCollection statementInformation; + + public SyntaxHighlighter(ReadOnlyCollection statementInformation) { - private readonly ReadOnlyCollection statementInformation; + this.statementInformation = statementInformation; + } - public SyntaxHighlighter(ReadOnlyCollection 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); } - - public void Write(string input) + else { - input = input.Replace("\0", string.Empty); - - if (input.StartsWith('#')) + MatchCollection matches = EscapeSequenceRegex().Matches(input); + for (int i = 0; i < matches.Count; i++) { - 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, @"!!."); - for (int i = 0; i < matches.Count; i++) + if (statement.IgnoreSyntaxHighlighting) { - 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; } - - 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); - } + input = AddColorInformation(input, input[..name.Length], statement.Color, statement.SearchMode); } - - matches = Regex.Matches(input, @">[a-zA-Z0-9]+"); - for (int i = 0; i < matches.Count; i++) + if (statement.SearchMode == SearchMode.Contains && $" {input} ".Contains(name)) { - 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); } - - matches = Regex.Matches(input, @"^<[a-zA-Z0-9]+"); - for (int i = 0; i < matches.Count; i++) + if (statement.SearchMode == SearchMode.EndOfLine && input.EndsWith(name)) { - 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); } - - matches = Regex.Matches(input, @"^!<[a-zA-Z0-9]+"); - for (int i = 0; i < matches.Count; i++) + if (statement.SearchMode == SearchMode.Exact && input.Equals(name)) { - 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; - string messagePart = part; + input = AddColorInformation(input, matches[i].Value, ConsoleColor.Cyan, SearchMode.Contains); + } - string stringColor = Regex.Match(messagePart, "(?<=(\\r))(.*)(?=\\r)").Value; - bool succ = int.TryParse(stringColor, out int colorIndex); - if (succ && colorIndex >= 0 && colorIndex < 16) - { - messagePart = messagePart.Replace($"\r{stringColor}\r", string.Empty); - consoleColor = (ConsoleColor)colorIndex; - } - else - { - consoleColor = ConsoleColor.White; - } + matches = VariableDeclarationRegex().Matches(input); + for (int i = 0; i < matches.Count; i++) + { + input = AddColorInformation(input, matches[i].Value, ConsoleColor.DarkCyan, SearchMode.StartOfLine); + } - if (consoleColor == Console.BackgroundColor) - { - consoleColor = ConsoleColor.White; - } - Console.ForegroundColor = consoleColor; - Console.Write(messagePart); + matches = GlobalVariableDeclarationRegex().Matches(input); + for (int i = 0; i < matches.Count; i++) + { + input = AddColorInformation(input, matches[i].Value, ConsoleColor.Blue, SearchMode.StartOfLine); } - 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(); - string reult = searchMode switch + ConsoleColor consoleColor; + 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)), - 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; + messagePart = messagePart.Replace($"\r{stringColor}\r", string.Empty); + consoleColor = (ConsoleColor)colorIndex; + } + else + { + 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(); } \ No newline at end of file diff --git a/YesNt.CodeEditor/YesNt.CodeEditor.csproj b/YesNt.CodeEditor/YesNt.CodeEditor.csproj index 16be40b..dd3b5de 100644 --- a/YesNt.CodeEditor/YesNt.CodeEditor.csproj +++ b/YesNt.CodeEditor/YesNt.CodeEditor.csproj @@ -2,7 +2,7 @@ Exe - net5.0 + net7.0 AnyCPU;x64 diff --git a/YesNt.Interpreter.Tests/YesNt.Interpreter.Tests.csproj b/YesNt.Interpreter.Tests/YesNt.Interpreter.Tests.csproj index 9e6dacd..5172e5e 100644 --- a/YesNt.Interpreter.Tests/YesNt.Interpreter.Tests.csproj +++ b/YesNt.Interpreter.Tests/YesNt.Interpreter.Tests.csproj @@ -1,7 +1,7 @@ - net6.0 + net7.0 enable false diff --git a/YesNt.Interpreter/Statements/ProcessingStatements.cs b/YesNt.Interpreter/Statements/ProcessingStatements.cs index 5efe797..2d80026 100644 --- a/YesNt.Interpreter/Statements/ProcessingStatements.cs +++ b/YesNt.Interpreter/Statements/ProcessingStatements.cs @@ -9,112 +9,112 @@ using YesNt.Interpreter.Enums; using YesNt.Interpreter.Runtime; 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)] - public void Calculate(string args) + for (int i = 0; i < matches.Count; i++) { - MatchCollection matches = calculationRegex.Matches(args.FromSaveString()); - - for (int i = 0; i < matches.Count; i++) + string res = Evaluator.Calculate(matches[i].Value); + if (res is null) { - string res = Evaluator.Calculate(matches[i].Value); - if (res is null) + RuntimeInfo.Exit("Invalid operation", true); + 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 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); - return; + RuntimeInfo.Lines.Insert(RuntimeInfo.LineNumber + i, new Line(lines[i], Path.GetFileName(path), i)); } - args = args.FromSaveString().Replace(matches[i].Value, res); + RuntimeInfo.LineNumber--; } - - 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) + catch { - 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.Exit($"Could not load file \"{path}\"", true); } - RuntimeInfo.CurrentLine = args; } - - [Statement("!task", SearchMode.EndOfLine, SpaceAround.Start, ConsoleColor.DarkYellow, Priority = Priority.VeryHigh)] - public void RunTask(string line) + else { - int lineNumer = RuntimeInfo.LineNumber; - List 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); - } + RuntimeInfo.Exit($"Could not find file \"{path}\"", true); } } + + [GeneratedRegex("[0-9*+().,^%/-]+[0-9*+ ().,^%/-]+[0-9*+().,^%/-]+")] + private static partial Regex CalculationRegex(); } \ No newline at end of file diff --git a/YesNt.Interpreter/Statements/VariableStatements.cs b/YesNt.Interpreter/Statements/VariableStatements.cs index 06194a2..98eb57d 100644 --- a/YesNt.Interpreter/Statements/VariableStatements.cs +++ b/YesNt.Interpreter/Statements/VariableStatements.cs @@ -5,119 +5,119 @@ using YesNt.Interpreter.Attributes; using YesNt.Interpreter.Enums; 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]+"); - - [Statement("<", SearchMode.StartOfLine, SpaceAround.None, Priority = Priority.VeryLow)] - public void DefineVariable(string args) + string[] parts = args.Split('='); + if (parts.Length == 2) { - string[] parts = args.Split('='); - if (parts.Length == 2) + string key = parts[0].Trim(); + if (key.Contains(' ')) { - string key = parts[0].Trim(); - 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()); - } + RuntimeInfo.Exit("Invalid Syntax", true); } - 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)) { - _ = RuntimeInfo.Variables.Remove(key); - } - else if (RuntimeInfo.GloablVariables.ContainsKey(key)) - { - _ = RuntimeInfo.GloablVariables.Remove(key); + RuntimeInfo.Variables[key] = parts[1].Trim(); } else { - RuntimeInfo.Exit($"Variable \"{key}\" not found", true); + RuntimeInfo.Variables.Add(key, parts[1].Trim()); } } - - [Statement(">", SearchMode.Contains, SpaceAround.None, Priority = Priority.Highest)] - public void ReadVariable(string _) + else { - 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 variable in RuntimeInfo.Variables) + { + RuntimeInfo.CurrentLine = RuntimeInfo.CurrentLine.Replace($">{variable.Key}", variable.Value); + } + + foreach (KeyValuePair 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; } - - foreach (KeyValuePair variable in RuntimeInfo.Variables) - { - RuntimeInfo.CurrentLine = RuntimeInfo.CurrentLine.Replace($">{variable.Key}", variable.Value); - } - - foreach (KeyValuePair 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(); } \ No newline at end of file diff --git a/YesNt.Interpreter/Utilities/Evaluator.cs b/YesNt.Interpreter/Utilities/Evaluator.cs index aac7d50..ecd39ff 100644 --- a/YesNt.Interpreter/Utilities/Evaluator.cs +++ b/YesNt.Interpreter/Utilities/Evaluator.cs @@ -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(); } \ No newline at end of file diff --git a/YesNt.Interpreter/Utilities/FixedProcess.cs b/YesNt.Interpreter/Utilities/FixedProcess.cs index 9ee542d..46ee530 100644 --- a/YesNt.Interpreter/Utilities/FixedProcess.cs +++ b/YesNt.Interpreter/Utilities/FixedProcess.cs @@ -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; diff --git a/YesNt.Interpreter/YesNt.Interpreter.csproj b/YesNt.Interpreter/YesNt.Interpreter.csproj index bd4ef12..3b71ea2 100644 --- a/YesNt.Interpreter/YesNt.Interpreter.csproj +++ b/YesNt.Interpreter/YesNt.Interpreter.csproj @@ -1,7 +1,7 @@  - net5.0 + net7.0 YesNt.Interpreter Exe