Upgrade to .NET 8 and code cleanup

This commit is contained in:
Stone_Red
2024-08-07 19:48:03 +02:00
parent 84afe70c96
commit 7078ed5637
33 changed files with 960 additions and 1008 deletions
+3
View File
@@ -114,3 +114,6 @@ dotnet_naming_style.pascal_case.required_prefix =
dotnet_naming_style.pascal_case.required_suffix = dotnet_naming_style.pascal_case.required_suffix =
dotnet_naming_style.pascal_case.word_separator = dotnet_naming_style.pascal_case.word_separator =
dotnet_naming_style.pascal_case.capitalization = pascal_case dotnet_naming_style.pascal_case.capitalization = pascal_case
# IDE0305: Simplify collection initialization
dotnet_diagnostic.IDE0305.severity = none
+5 -11
View File
@@ -11,12 +11,12 @@ internal class TextEditor
{ {
private readonly InputHandler inputHandler; private readonly InputHandler inputHandler;
private readonly SyntaxHighlighter syntaxHighlighter; private readonly SyntaxHighlighter syntaxHighlighter;
private readonly List<string> debugOutput = new(); private readonly List<string> debugOutput = [];
private readonly Point oldSize = new Point(0, 0); private readonly Point oldSize = new Point(0, 0);
public YesNtInterpreter YesNtInterpreter { get; } = new(); public YesNtInterpreter YesNtInterpreter { get; } = new();
public int LineOffset { get; set; } = 0; public int LineOffset { get; set; } = 0;
public List<string> Lines { get; } = new(); public List<string> Lines { get; } = [];
public Point CursorPosition { get; } = new(0, 0); public Point CursorPosition { get; } = new(0, 0);
public Mode EditMode { get; set; } = Mode.Command; public Mode EditMode { get; set; } = Mode.Command;
public string CurrentPath { get; set; } = string.Empty; public string CurrentPath { get; set; } = string.Empty;
@@ -263,16 +263,10 @@ internal class TextEditor
} }
} }
internal class Point internal class Point(int x, int y)
{ {
public int X { get; set; } public int X { get; set; } = x;
public int Y { get; set; } public int Y { get; set; } = y;
public Point(int x, int y)
{
X = x;
Y = y;
}
} }
internal enum Mode internal enum Mode
+2 -7
View File
@@ -3,14 +3,9 @@ using System.Text;
namespace YesNt.CodeEditor; namespace YesNt.CodeEditor;
internal class InputHandler internal class InputHandler(TextEditor textEditor)
{ {
private readonly TextEditor textEditor; private readonly TextEditor textEditor = textEditor;
public InputHandler(TextEditor textEditor)
{
this.textEditor = textEditor;
}
public bool HandleInput() public bool HandleInput()
{ {
@@ -1,12 +1,12 @@
{ {
"profiles": { "profiles": {
"YesNt.CodeEditor": { "YesNt.CodeEditor": {
"commandName": "Project" "commandName": "Project"
}, },
"WSL": { "WSL": {
"commandName": "WSL2", "commandName": "WSL2",
"environmentVariables": {}, "environmentVariables": {},
"distributionName": "" "distributionName": ""
}
} }
}
} }
+17 -23
View File
@@ -9,16 +9,10 @@ using YesNt.Interpreter.Utilities;
namespace YesNt.CodeEditor; namespace YesNt.CodeEditor;
internal partial class SyntaxHighlighter internal partial class SyntaxHighlighter(ReadOnlyCollection<StatementInformation> statementInformation)
{ {
private readonly ReadOnlyCollection<StatementInformation> statementInformation; private readonly ReadOnlyCollection<StatementInformation> statementInformation = statementInformation;
private readonly string[] replacementValues; private readonly string[] replacementValues = StringExtensions.ReplacementRules.Values.ToArray();
public SyntaxHighlighter(ReadOnlyCollection<StatementInformation> statementInformation)
{
this.statementInformation = statementInformation;
replacementValues = StringExtentions.ReplacementRules.Values.ToArray();
}
public static string Base64Encode(string plainText) public static string Base64Encode(string plainText)
{ {
@@ -64,11 +58,11 @@ internal partial class SyntaxHighlighter
input = input.TrimEnd(' '); input = input.TrimEnd(' ');
if (statement.SearchMode == SearchMode.StartOfLine && input.StartsWith(name)) if (statement.SearchMode == SearchMode.StartOfLine && input.StartsWith(name))
{ {
if (statement.Seperator is not null && input.Contains(statement.Seperator)) if (statement.Separator is not null && input.Contains(statement.Separator))
{ {
input = AddColorInformation(input, statement.Seperator, statement.Color, SearchMode.StartOfLine); input = AddColorInformation(input, statement.Separator, statement.Color, SearchMode.StartOfLine);
} }
else if (statement.Seperator is not null) else if (statement.Separator is not null)
{ {
continue; continue;
} }
@@ -76,11 +70,11 @@ internal partial class SyntaxHighlighter
} }
else if (statement.SearchMode == SearchMode.Contains && input.Contains(name)) else if (statement.SearchMode == SearchMode.Contains && input.Contains(name))
{ {
if (statement.Seperator is not null && input.Contains(statement.Seperator)) if (statement.Separator is not null && input.Contains(statement.Separator))
{ {
input = AddColorInformation(input, statement.Seperator, statement.Color, SearchMode.StartOfLine); input = AddColorInformation(input, statement.Separator, statement.Color, SearchMode.StartOfLine);
} }
else if (statement.Seperator is not null) else if (statement.Separator is not null)
{ {
continue; continue;
} }
@@ -88,11 +82,11 @@ internal partial class SyntaxHighlighter
} }
else if (statement.SearchMode == SearchMode.EndOfLine && input.EndsWith(name)) else if (statement.SearchMode == SearchMode.EndOfLine && input.EndsWith(name))
{ {
if (statement.Seperator is not null && input.Contains(statement.Seperator)) if (statement.Separator is not null && input.Contains(statement.Separator))
{ {
input = AddColorInformation(input, statement.Seperator, statement.Color, SearchMode.StartOfLine); input = AddColorInformation(input, statement.Separator, statement.Color, SearchMode.StartOfLine);
} }
else if (statement.Seperator is not null) else if (statement.Separator is not null)
{ {
continue; continue;
} }
@@ -100,11 +94,11 @@ internal partial class SyntaxHighlighter
} }
else if (statement.SearchMode == SearchMode.Exact && input.Equals(name)) else if (statement.SearchMode == SearchMode.Exact && input.Equals(name))
{ {
if (statement.Seperator is not null && input.Contains(statement.Seperator)) if (statement.Separator is not null && input.Contains(statement.Separator))
{ {
input = AddColorInformation(input, statement.Seperator, statement.Color, SearchMode.StartOfLine); input = AddColorInformation(input, statement.Separator, statement.Color, SearchMode.StartOfLine);
} }
else if (statement.Seperator is not null) else if (statement.Separator is not null)
{ {
continue; continue;
} }
@@ -164,13 +158,13 @@ internal partial class SyntaxHighlighter
string base64Value = Base64Encode(value.TrimEnd()); string base64Value = Base64Encode(value.TrimEnd());
string reult = searchMode switch string result = searchMode switch
{ {
SearchMode.StartOfLine => originalString.ReplaceFirstOccurrence(value, $"\0\r{(int)color}\r{base64Value}\0" + new string(' ', spacesAtEnd)), SearchMode.StartOfLine => originalString.ReplaceFirstOccurrence(value, $"\0\r{(int)color}\r{base64Value}\0" + new string(' ', spacesAtEnd)),
SearchMode.EndOfLine => originalString.ReplaceLastOccurrence(value, $"\0\r{(int)color}\r{base64Value}\0" + new string(' ', spacesAtEnd)), SearchMode.EndOfLine => originalString.ReplaceLastOccurrence(value, $"\0\r{(int)color}\r{base64Value}\0" + new string(' ', spacesAtEnd)),
_ => originalString.Replace(value, $"\0\r{(int)color}\r{base64Value}\0" + new string(' ', spacesAtEnd)) _ => originalString.Replace(value, $"\0\r{(int)color}\r{base64Value}\0" + new string(' ', spacesAtEnd))
}; };
return reult; return result;
} }
[GeneratedRegex("^<[a-zA-Z0-9]+")] [GeneratedRegex("^<[a-zA-Z0-9]+")]
+1 -1
View File
@@ -2,7 +2,7 @@
<PropertyGroup> <PropertyGroup>
<OutputType>Exe</OutputType> <OutputType>Exe</OutputType>
<TargetFramework>net7.0</TargetFramework> <TargetFramework>net8.0</TargetFramework>
<Platforms>AnyCPU;x64</Platforms> <Platforms>AnyCPU;x64</Platforms>
</PropertyGroup> </PropertyGroup>
+6 -6
View File
@@ -10,28 +10,28 @@ public class CodeFlowTests
[TestMethod] [TestMethod]
public void FunctionTest() public void FunctionTest()
{ {
List<string> lines = new List<string>() List<string> lines =
{ [
"cal yes", "cal yes",
"fnc yes", "fnc yes",
"!<result = 1", "!<result = 1",
"ret", "ret",
">result" ">result"
}; ];
YesNtAssert.IsLastLineEqual(lines, "1"); YesNtAssert.IsLastLineEqual(lines, "1");
} }
[TestMethod] [TestMethod]
public void LabelsTest() public void LabelsTest()
{ {
List<string> lines = new List<string>() List<string> lines =
{ [
"<result = 1", "<result = 1",
"jmp yes", "jmp yes",
"<result = 0", "<result = 0",
"lbl yes", "lbl yes",
">result" ">result"
}; ];
YesNtAssert.IsLastLineEqual(lines, "1"); YesNtAssert.IsLastLineEqual(lines, "1");
} }
@@ -1,7 +1,7 @@
<Project Sdk="Microsoft.NET.Sdk"> <Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup> <PropertyGroup>
<TargetFramework>net7.0</TargetFramework> <TargetFramework>net8.0</TargetFramework>
<Nullable>enable</Nullable> <Nullable>enable</Nullable>
<IsPackable>false</IsPackable> <IsPackable>false</IsPackable>
+6 -6
View File
@@ -42,10 +42,10 @@ internal static class YesNtAssert
public static void IsLineEqual(string line, string expected, int timeout = 1000) public static void IsLineEqual(string line, string expected, int timeout = 1000)
{ {
AutoResetEvent onDone = new AutoResetEvent(false); AutoResetEvent onDone = new AutoResetEvent(false);
List<string> lines = new List<string>() List<string> lines =
{ [
line line
}; ];
DebugEventArgs debugEventArgs = new DebugEventArgs(); DebugEventArgs debugEventArgs = new DebugEventArgs();
yesNtInterpreter.OnLineExecuted += (er) => yesNtInterpreter.OnLineExecuted += (er) =>
@@ -64,10 +64,10 @@ internal static class YesNtAssert
public static void IsLineNotEqual(string line, string expected, int timeout = 1000) public static void IsLineNotEqual(string line, string expected, int timeout = 1000)
{ {
AutoResetEvent onDone = new AutoResetEvent(false); AutoResetEvent onDone = new AutoResetEvent(false);
List<string> lines = new List<string>() List<string> lines =
{ [
line line
}; ];
DebugEventArgs debugEventArgs = new DebugEventArgs(); DebugEventArgs debugEventArgs = new DebugEventArgs();
yesNtInterpreter.OnLineExecuted += (er) => yesNtInterpreter.OnLineExecuted += (er) =>
@@ -2,35 +2,34 @@
using YesNt.Interpreter.Enums; using YesNt.Interpreter.Enums;
namespace YesNt.Interpreter.Attributes namespace YesNt.Interpreter.Attributes;
[AttributeUsage(AttributeTargets.Method, AllowMultiple = false)]
internal class StatementAttribute : Attribute
{ {
[AttributeUsage(AttributeTargets.Method, AllowMultiple = false)] public string Name { get; }
internal class StatementAttribute : Attribute public SearchMode SearchMode { get; }
public SpaceAround SpaceAround { get; }
public ConsoleColor Color { get; set; }
public Priority Priority { get; set; } = Priority.Normal;
public bool ExecuteInSearchMode { get; set; }
public bool KeepStatementInArgs { get; set; }
public bool IgnoreSyntaxHighlighting { get; }
public string Separator { get; set; }
internal StatementAttribute(string name, SearchMode searchMode, SpaceAround spaceAround, ConsoleColor color)
{ {
public string Name { get; } Name = name;
public SearchMode SearchMode { get; } SearchMode = searchMode;
public SpaceAround SpaceAround { get; } SpaceAround = spaceAround;
public ConsoleColor Color { get; set; } Color = color;
public Priority Priority { get; set; } = Priority.Normal; }
public bool ExecuteInSearchMode { get; set; }
public bool KeepStatementInArgs { get; set; }
public bool IgnoreSyntaxHighlighting { get; }
public string Seperator { get; set; }
internal StatementAttribute(string name, SearchMode searchMode, SpaceAround spaceAround, ConsoleColor color) internal StatementAttribute(string name, SearchMode searchMode, SpaceAround spaceAround)
{ {
Name = name; Name = name;
SearchMode = searchMode; SearchMode = searchMode;
SpaceAround = spaceAround; SpaceAround = spaceAround;
Color = color; IgnoreSyntaxHighlighting = true;
}
internal StatementAttribute(string name, SearchMode searchMode, SpaceAround spaceAround)
{
Name = name;
SearchMode = searchMode;
SpaceAround = spaceAround;
IgnoreSyntaxHighlighting = true;
}
} }
} }
@@ -2,12 +2,11 @@
using YesNt.Interpreter.Enums; using YesNt.Interpreter.Enums;
namespace YesNt.Interpreter.Attributes namespace YesNt.Interpreter.Attributes;
[AttributeUsage(AttributeTargets.Method, AllowMultiple = false)]
internal class StaticStatementAttribute : Attribute
{ {
[AttributeUsage(AttributeTargets.Method, AllowMultiple = false)] public bool ExecuteInSearchMode { get; set; }
internal class StaticStatementAttribute : Attribute public Priority Priority { get; set; } = Priority.Normal;
{
public bool ExecuteInSearchMode { get; set; }
public Priority Priority { get; set; } = Priority.Normal;
}
} }
+10 -11
View File
@@ -1,13 +1,12 @@
namespace YesNt.Interpreter.Enums namespace YesNt.Interpreter.Enums;
internal enum Priority
{ {
internal enum Priority PreProcessing,
{ Highest,
PreProcessing, VeryHigh,
Highest, High,
VeryHigh, Normal,
High, Low,
Normal, VeryLow
Low,
VeryLow
}
} }
+7 -8
View File
@@ -1,10 +1,9 @@
namespace YesNt.Interpreter.Enums namespace YesNt.Interpreter.Enums;
public enum SearchMode
{ {
public enum SearchMode StartOfLine,
{ EndOfLine,
StartOfLine, Contains,
EndOfLine, Exact
Contains,
Exact
}
} }
+7 -8
View File
@@ -1,10 +1,9 @@
namespace YesNt.Interpreter.Enums namespace YesNt.Interpreter.Enums;
public enum SpaceAround
{ {
public enum SpaceAround StartEnd,
{ Start,
StartEnd, End,
Start, None
End,
None
}
} }
+8 -17
View File
@@ -2,22 +2,13 @@
using YesNt.Interpreter.Runtime; using YesNt.Interpreter.Runtime;
namespace YesNt.Interpreter if (args.Length == 1)
{ {
internal static class Program YesNtInterpreter interpreter = new YesNtInterpreter();
{ interpreter.Initialize();
private static void Main(string[] args) interpreter.Execute(args[0]);
{ }
if (args.Length == 1) else
{ {
YesNtInterpreter interpreter = new YesNtInterpreter(); Console.WriteLine("No path specified!");
interpreter.Initialize();
interpreter.Execute(args[0]);
}
else
{
Console.WriteLine("No path specified!");
}
}
}
} }
@@ -1,13 +1,13 @@
{ {
"profiles": { "profiles": {
"YesNt-Interpreter": { "YesNt-Interpreter": {
"commandName": "Project", "commandName": "Project",
"commandLineArgs": "code.ynt" "commandLineArgs": "code.ynt"
}, },
"WSL": { "WSL": {
"commandName": "WSL2", "commandName": "WSL2",
"environmentVariables": {}, "environmentVariables": {},
"distributionName": "" "distributionName": ""
}
} }
}
} }
+8 -9
View File
@@ -1,13 +1,12 @@
using System; using System;
namespace YesNt.Interpreter.Runtime namespace YesNt.Interpreter.Runtime;
public class DebugEventArgs : EventArgs
{ {
public class DebugEventArgs : EventArgs public int LineNumber { get; internal set; }
{ public string CurrentLine { get; internal set; }
public int LineNumber { get; internal set; } public string OriginalLine { get; internal set; }
public string CurrentLine { get; internal set; } public int TaskId { get; internal set; }
public string OriginalLine { get; internal set; } public bool IsTask { get; internal set; }
public int TaskId { get; internal set; }
public bool IsTask { get; internal set; }
}
} }
+5 -11
View File
@@ -2,17 +2,11 @@
namespace YesNt.Interpreter.Runtime; namespace YesNt.Interpreter.Runtime;
internal class FunctionScope internal class FunctionScope(int callerLine, Stack<string> arguments)
{ {
public int CallerLine { get; } public int CallerLine { get; } = callerLine;
public Dictionary<string, string> Variables { get; } = new(); public Dictionary<string, string> Variables { get; } = [];
public Dictionary<string, int> Labels { get; } = new(); public Dictionary<string, int> Labels { get; } = [];
public Stack<string> Arguemtns { get; } public Stack<string> Arguments { get; } = arguments;
public Stack<string> Results { get; } = new(); public Stack<string> Results { get; } = new();
public FunctionScope(int callerLine, Stack<string> arguemtns)
{
CallerLine = callerLine;
Arguemtns = arguemtns;
}
} }
+8 -14
View File
@@ -1,16 +1,10 @@
namespace YesNt.Interpreter.Runtime namespace YesNt.Interpreter.Runtime;
{
internal class Line
{
public Line(string content, string fileName, int lineNumber)
{
Content = content;
FileName = fileName;
LineNumber = lineNumber;
}
public string Content { get; set; } internal class Line(string content, string fileName, int lineNumber)
public string FileName { get; set; } {
public int LineNumber { get; set; } public string Content { get; set; } = content;
}
public string FileName { get; set; } = fileName;
public int LineNumber { get; set; } = lineNumber;
} }
@@ -14,16 +14,16 @@ internal sealed class RuntimeInformation
private event Action<string, bool> OnExit; private event Action<string, bool> OnExit;
private static int internalTaskId = 0; private static int internalTaskId = 0;
private readonly Dictionary<string, string> topVariables = new(); private readonly Dictionary<string, string> topVariables = [];
private readonly Dictionary<string, int> topLabels = new(); private readonly Dictionary<string, int> topLabels = [];
private RuntimeInformation parentRuntimeInformation; private RuntimeInformation parentRuntimeInformation;
private int taskId = 0; private int taskId = 0;
public Dictionary<string, string> GloablVariables { get; set; } = new(); public Dictionary<string, string> GlobalVariables { get; set; } = [];
public Dictionary<string, int> Functions { get; } = new(); public Dictionary<string, int> Functions { get; } = [];
public Stack<FunctionScope> FunctionCallStack { get; } = new(); public Stack<FunctionScope> FunctionCallStack { get; } = new();
public Stack<string> InParametersStack { get; } = new(); public Stack<string> InParametersStack { get; } = new();
public Stack<string> OutParametersStack { get; set; } = new(); public Stack<string> OutParametersStack { get; set; } = new();
public List<Line> Lines { get; set; } = new(); public List<Line> Lines { get; set; } = [];
public string CurrentLine { get; set; } = string.Empty; public string CurrentLine { get; set; } = string.Empty;
public string SearchLabel { get; set; } = string.Empty; public string SearchLabel { get; set; } = string.Empty;
public string SearchFunction { get; set; } = string.Empty; public string SearchFunction { get; set; } = string.Empty;
@@ -149,7 +149,7 @@ internal sealed class RuntimeInformation
{ {
topVariables.Clear(); topVariables.Clear();
Lines.Clear(); Lines.Clear();
GloablVariables.Clear(); GlobalVariables.Clear();
Labels.Clear(); Labels.Clear();
Functions.Clear(); Functions.Clear();
FunctionCallStack.Clear(); FunctionCallStack.Clear();
@@ -2,15 +2,14 @@
using YesNt.Interpreter.Enums; using YesNt.Interpreter.Enums;
namespace YesNt.Interpreter.Runtime namespace YesNt.Interpreter.Runtime;
public class StatementInformation
{ {
public class StatementInformation public string Name { get; internal set; }
{ public SearchMode SearchMode { get; internal set; }
public string Name { get; internal set; } public SpaceAround SpaceAround { get; internal set; }
public SearchMode SearchMode { get; internal set; } public ConsoleColor Color { get; internal set; }
public SpaceAround SpaceAround { get; internal set; } public bool IgnoreSyntaxHighlighting { get; internal set; }
public ConsoleColor Color { get; internal set; } public string Separator { get; set; }
public bool IgnoreSyntaxHighlighting { get; internal set; }
public string Seperator { get; set; }
}
} }
@@ -1,7 +1,6 @@
namespace YesNt.Interpreter.Runtime namespace YesNt.Interpreter.Runtime;
internal abstract class StatementRuntimeInformation
{ {
internal abstract class StatementRuntimeInformation public RuntimeInformation RuntimeInfo { get; set; }
{
public RuntimeInformation RuntimeInfo { get; set; }
}
} }
@@ -18,14 +18,14 @@ public class YesNtInterpreter
public event Action<string> OnDebugOutput; public event Action<string> OnDebugOutput;
private readonly RuntimeInformation runtimeInfo = new RuntimeInformation(); private readonly RuntimeInformation runtimeInfo = new RuntimeInformation();
private Dictionary<StatementAttribute, Action<string>> statements = new(); private Dictionary<StatementAttribute, Action<string>> statements = [];
private List<KeyValuePair<StaticStatementAttribute, Action>> staticStatements = new(); private List<KeyValuePair<StaticStatementAttribute, Action>> staticStatements = [];
public ReadOnlyCollection<StatementInformation> StatementInformation public ReadOnlyCollection<StatementInformation> StatementInformation
{ {
get get
{ {
List<StatementInformation> informations = statements.Select(s => List<StatementInformation> information = statements.Select(s =>
{ {
return new StatementInformation() return new StatementInformation()
{ {
@@ -34,11 +34,11 @@ public class YesNtInterpreter
SpaceAround = s.Key.SpaceAround, SpaceAround = s.Key.SpaceAround,
Color = s.Key.Color, Color = s.Key.Color,
IgnoreSyntaxHighlighting = s.Key.IgnoreSyntaxHighlighting, IgnoreSyntaxHighlighting = s.Key.IgnoreSyntaxHighlighting,
Seperator = s.Key.Seperator Separator = s.Key.Separator
}; };
}).ToList(); }).ToList();
return new ReadOnlyCollection<StatementInformation>(informations); return new ReadOnlyCollection<StatementInformation>(information);
} }
} }
@@ -118,14 +118,14 @@ public class YesNtInterpreter
Execute(); Execute();
} }
internal void Execute(List<Line> lines, Dictionary<string, string> gloablVariables, int startLine, RuntimeInformation parentRuntimeInformation) internal void Execute(List<Line> lines, Dictionary<string, string> globalVariables, int startLine, RuntimeInformation parentRuntimeInformation)
{ {
runtimeInfo.Reset(); runtimeInfo.Reset();
runtimeInfo.IsDebugMode = parentRuntimeInformation.IsDebugMode; runtimeInfo.IsDebugMode = parentRuntimeInformation.IsDebugMode;
runtimeInfo.Lines = lines; runtimeInfo.Lines = lines;
runtimeInfo.LineNumber = startLine; runtimeInfo.LineNumber = startLine;
runtimeInfo.ParentRuntimeInformation = parentRuntimeInformation; runtimeInfo.ParentRuntimeInformation = parentRuntimeInformation;
runtimeInfo.GloablVariables = gloablVariables; runtimeInfo.GlobalVariables = globalVariables;
if (parentRuntimeInformation.StopAllTasks) if (parentRuntimeInformation.StopAllTasks)
{ {
runtimeInfo.Exit($"Parent task was terminated!", parentRuntimeInformation.StopAllTasks); runtimeInfo.Exit($"Parent task was terminated!", parentRuntimeInformation.StopAllTasks);
@@ -195,7 +195,7 @@ public class YesNtInterpreter
_ => statementAttribute.Name.Trim() _ => statementAttribute.Name.Trim()
}; };
if (statementAttribute.Seperator is null || runtimeInfo.CurrentLine.Contains(statementAttribute.Seperator)) if (statementAttribute.Separator is null || runtimeInfo.CurrentLine.Contains(statementAttribute.Separator))
{ {
if (statementAttribute.SearchMode == SearchMode.StartOfLine && runtimeInfo.CurrentLine.StartsWith(name)) if (statementAttribute.SearchMode == SearchMode.StartOfLine && runtimeInfo.CurrentLine.StartsWith(name))
{ {
+180 -181
View File
@@ -7,192 +7,191 @@ 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 class CodeFlowStatements : StatementRuntimeInformation
{ {
internal class CodeFlowStatements : StatementRuntimeInformation [Statement("jmp", SearchMode.StartOfLine, SpaceAround.End, ConsoleColor.Green, Priority = Priority.VeryLow)]
public void Jump(string args)
{ {
[Statement("jmp", SearchMode.StartOfLine, SpaceAround.End, ConsoleColor.Green, Priority = Priority.VeryLow)] string key = args.Trim();
public void Jump(string args)
{
string key = args.Trim();
if (RuntimeInfo.Labels.ContainsKey(key)) if (RuntimeInfo.Labels.TryGetValue(key, out int value))
{ {
RuntimeInfo.LineNumber = RuntimeInfo.Labels[key]; RuntimeInfo.LineNumber = value;
}
else
{
RuntimeInfo.SearchLabel = key;
RuntimeInfo.IsLocalSearch = RuntimeInfo.IsInFunction;
}
} }
else
[Statement("jif", SearchMode.StartOfLine, SpaceAround.End, ConsoleColor.Green, Priority = Priority.VeryLow, Seperator = "|")]
public void JumpIf(string args)
{ {
string[] parts = args.Split('|'); RuntimeInfo.SearchLabel = key;
if (parts.Length != 2) RuntimeInfo.IsLocalSearch = RuntimeInfo.IsInFunction;
{
RuntimeInfo.Exit("Invalid syntax", true);
return;
}
string key = parts[0].Trim();
string condition = parts[1].Trim();
bool? result = Evaluator.EvaluateCondition(condition);
if (result is null)
{
RuntimeInfo.Exit("Invalid operation", true);
return;
}
if (result == false)
{
return;
}
if (RuntimeInfo.Labels.ContainsKey(key))
{
RuntimeInfo.LineNumber = RuntimeInfo.Labels[key];
}
else
{
RuntimeInfo.SearchLabel = key;
RuntimeInfo.IsLocalSearch = RuntimeInfo.IsInFunction;
}
}
[Statement("lbl", SearchMode.StartOfLine, SpaceAround.End, ConsoleColor.Green, ExecuteInSearchMode = true)]
public void FindLabel(string args)
{
string key = args.Trim();
if (RuntimeInfo.Labels.ContainsKey(key))
{
RuntimeInfo.Labels[key] = RuntimeInfo.LineNumber;
}
else
{
RuntimeInfo.Labels.Add(key, RuntimeInfo.LineNumber);
}
if (!string.IsNullOrWhiteSpace(RuntimeInfo.SearchLabel) && RuntimeInfo.SearchLabel == key)
{
RuntimeInfo.SearchLabel = string.Empty;
RuntimeInfo.IsLocalSearch = false;
}
}
[Statement("cal", SearchMode.StartOfLine, SpaceAround.End, ConsoleColor.DarkYellow, Priority = Priority.VeryLow)]
public void Call(string args)
{
string key = args.Trim();
RuntimeInfo.FunctionCallStack.Push(new FunctionScope(RuntimeInfo.LineNumber, new Stack<string>(RuntimeInfo.InParametersStack.Reverse())));
RuntimeInfo.InParametersStack.Clear();
if (RuntimeInfo.Functions.ContainsKey(key))
{
RuntimeInfo.LineNumber = RuntimeInfo.Functions[key];
}
else
{
RuntimeInfo.SearchFunction = key;
}
}
[Statement("cif", SearchMode.StartOfLine, SpaceAround.End, ConsoleColor.DarkYellow, Priority = Priority.VeryLow, Seperator = "|")]
public void CallIf(string args)
{
string[] parts = args.Split('|');
if (parts.Length != 2)
{
RuntimeInfo.Exit("Invalid syntax", true);
return;
}
string key = parts[0].Trim();
string condition = parts[1].Trim();
bool? result = Evaluator.EvaluateCondition(condition);
if (result is null)
{
RuntimeInfo.Exit("Invalid operation", true);
return;
}
if (result == false)
{
return;
}
RuntimeInfo.FunctionCallStack.Push(new FunctionScope(RuntimeInfo.LineNumber, new Stack<string>(RuntimeInfo.InParametersStack)));
RuntimeInfo.InParametersStack.Clear();
if (RuntimeInfo.Functions.ContainsKey(key))
{
RuntimeInfo.LineNumber = RuntimeInfo.Functions[key];
}
else
{
RuntimeInfo.SearchFunction = key;
}
}
[Statement("end", SearchMode.Exact, SpaceAround.None, ConsoleColor.Red, ExecuteInSearchMode = true)]
public void End(string _)
{
if (RuntimeInfo.IsSearching)
{
RuntimeInfo.IsInFunction = false;
if (RuntimeInfo.IsLocalSearch)
{
RuntimeInfo.Exit($"Label \"{RuntimeInfo.SearchLabel}\" not found", true);
}
return;
}
else
{
RuntimeInfo.IsInFunction = false;
}
RuntimeInfo.Exit("Planned termination by code", false);
}
[Statement("trm", SearchMode.Exact, SpaceAround.None, ConsoleColor.Red, ExecuteInSearchMode = true)]
public void Terminate(string _)
{
if (RuntimeInfo.IsSearching)
{
RuntimeInfo.IsInFunction = false;
if (RuntimeInfo.IsLocalSearch)
{
RuntimeInfo.Exit($"Label \"{RuntimeInfo.SearchLabel}\" not found", true);
}
return;
}
else
{
RuntimeInfo.IsInFunction = false;
}
RuntimeInfo.Exit("Planned termination by code. Canceling all tasks", true);
}
[Statement("trw", SearchMode.StartOfLine, SpaceAround.End, ConsoleColor.Red)]
public void Throw(string message)
{
RuntimeInfo.Exit(message, true);
}
[Statement("err", SearchMode.StartOfLine, SpaceAround.End, ConsoleColor.Red)]
public void Error(string message)
{
RuntimeInfo.Exit(message, false);
} }
} }
[Statement("jif", SearchMode.StartOfLine, SpaceAround.End, ConsoleColor.Green, Priority = Priority.VeryLow, Separator = "|")]
public void JumpIf(string args)
{
string[] parts = args.Split('|');
if (parts.Length != 2)
{
RuntimeInfo.Exit("Invalid syntax", true);
return;
}
string key = parts[0].Trim();
string condition = parts[1].Trim();
bool? result = Evaluator.EvaluateCondition(condition);
if (result is null)
{
RuntimeInfo.Exit("Invalid operation", true);
return;
}
if (result == false)
{
return;
}
if (RuntimeInfo.Labels.TryGetValue(key, out int value))
{
RuntimeInfo.LineNumber = value;
}
else
{
RuntimeInfo.SearchLabel = key;
RuntimeInfo.IsLocalSearch = RuntimeInfo.IsInFunction;
}
}
[Statement("lbl", SearchMode.StartOfLine, SpaceAround.End, ConsoleColor.Green, ExecuteInSearchMode = true)]
public void FindLabel(string args)
{
string key = args.Trim();
if (RuntimeInfo.Labels.ContainsKey(key))
{
RuntimeInfo.Labels[key] = RuntimeInfo.LineNumber;
}
else
{
RuntimeInfo.Labels.Add(key, RuntimeInfo.LineNumber);
}
if (!string.IsNullOrWhiteSpace(RuntimeInfo.SearchLabel) && RuntimeInfo.SearchLabel == key)
{
RuntimeInfo.SearchLabel = string.Empty;
RuntimeInfo.IsLocalSearch = false;
}
}
[Statement("cal", SearchMode.StartOfLine, SpaceAround.End, ConsoleColor.DarkYellow, Priority = Priority.VeryLow)]
public void Call(string args)
{
string key = args.Trim();
RuntimeInfo.FunctionCallStack.Push(new FunctionScope(RuntimeInfo.LineNumber, new Stack<string>(RuntimeInfo.InParametersStack.Reverse())));
RuntimeInfo.InParametersStack.Clear();
if (RuntimeInfo.Functions.TryGetValue(key, out int value))
{
RuntimeInfo.LineNumber = value;
}
else
{
RuntimeInfo.SearchFunction = key;
}
}
[Statement("cif", SearchMode.StartOfLine, SpaceAround.End, ConsoleColor.DarkYellow, Priority = Priority.VeryLow, Separator = "|")]
public void CallIf(string args)
{
string[] parts = args.Split('|');
if (parts.Length != 2)
{
RuntimeInfo.Exit("Invalid syntax", true);
return;
}
string key = parts[0].Trim();
string condition = parts[1].Trim();
bool? result = Evaluator.EvaluateCondition(condition);
if (result is null)
{
RuntimeInfo.Exit("Invalid operation", true);
return;
}
if (result == false)
{
return;
}
RuntimeInfo.FunctionCallStack.Push(new FunctionScope(RuntimeInfo.LineNumber, new Stack<string>(RuntimeInfo.InParametersStack)));
RuntimeInfo.InParametersStack.Clear();
if (RuntimeInfo.Functions.TryGetValue(key, out int value))
{
RuntimeInfo.LineNumber = value;
}
else
{
RuntimeInfo.SearchFunction = key;
}
}
[Statement("end", SearchMode.Exact, SpaceAround.None, ConsoleColor.Red, ExecuteInSearchMode = true)]
public void End(string _)
{
if (RuntimeInfo.IsSearching)
{
RuntimeInfo.IsInFunction = false;
if (RuntimeInfo.IsLocalSearch)
{
RuntimeInfo.Exit($"Label \"{RuntimeInfo.SearchLabel}\" not found", true);
}
return;
}
else
{
RuntimeInfo.IsInFunction = false;
}
RuntimeInfo.Exit("Planned termination by code", false);
}
[Statement("trm", SearchMode.Exact, SpaceAround.None, ConsoleColor.Red, ExecuteInSearchMode = true)]
public void Terminate(string _)
{
if (RuntimeInfo.IsSearching)
{
RuntimeInfo.IsInFunction = false;
if (RuntimeInfo.IsLocalSearch)
{
RuntimeInfo.Exit($"Label \"{RuntimeInfo.SearchLabel}\" not found", true);
}
return;
}
else
{
RuntimeInfo.IsInFunction = false;
}
RuntimeInfo.Exit("Planned termination by code. Canceling all tasks", true);
}
[Statement("trw", SearchMode.StartOfLine, SpaceAround.End, ConsoleColor.Red)]
public void Throw(string message)
{
RuntimeInfo.Exit(message, true);
}
[Statement("err", SearchMode.StartOfLine, SpaceAround.End, ConsoleColor.Red)]
public void Error(string message)
{
RuntimeInfo.Exit(message, false);
}
} }
+172 -173
View File
@@ -5,196 +5,195 @@ 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 class FunctionStatements : StatementRuntimeInformation
{ {
internal class FunctionStatements : StatementRuntimeInformation [Statement("fnc", SearchMode.StartOfLine, SpaceAround.End, ConsoleColor.DarkYellow, ExecuteInSearchMode = true)]
public void FindFunction(string args)
{ {
[Statement("fnc", SearchMode.StartOfLine, SpaceAround.End, ConsoleColor.DarkYellow, ExecuteInSearchMode = true)] if (RuntimeInfo.InternalIsInFunction)
public void FindFunction(string args)
{ {
if (RuntimeInfo.InternalIsInFunction) RuntimeInfo.Exit("Nested functions are not allowed", true);
{ return;
RuntimeInfo.Exit("Nested functions are not allowed", true);
return;
}
string key = args.Trim();
if (RuntimeInfo.Functions.ContainsKey(key))
{
RuntimeInfo.Functions[key] = RuntimeInfo.LineNumber;
}
else
{
RuntimeInfo.Functions.Add(key, RuntimeInfo.LineNumber);
}
if (!string.IsNullOrWhiteSpace(RuntimeInfo.SearchFunction) && RuntimeInfo.SearchFunction == key)
{
RuntimeInfo.SearchFunction = string.Empty;
}
RuntimeInfo.IsInFunction = true;
} }
[Statement("in", SearchMode.StartOfLine, SpaceAround.End, ConsoleColor.Yellow)] string key = args.Trim();
public void AddInParameter(string args) if (RuntimeInfo.Functions.ContainsKey(key))
{ {
RuntimeInfo.InParametersStack.Push(args); RuntimeInfo.Functions[key] = RuntimeInfo.LineNumber;
}
else
{
RuntimeInfo.Functions.Add(key, RuntimeInfo.LineNumber);
} }
[Statement("out", SearchMode.StartOfLine, SpaceAround.End, ConsoleColor.Yellow)] if (!string.IsNullOrWhiteSpace(RuntimeInfo.SearchFunction) && RuntimeInfo.SearchFunction == key)
public void GetOutParameter(string args)
{ {
if (RuntimeInfo.OutParametersStack.Count == 0) RuntimeInfo.SearchFunction = string.Empty;
{
RuntimeInfo.Exit("No out argument in stack", true);
return;
}
if (RuntimeInfo.Variables.ContainsKey(args))
{
RuntimeInfo.Variables[args] = RuntimeInfo.OutParametersStack.Pop();
}
else
{
RuntimeInfo.Variables.Add(args, RuntimeInfo.OutParametersStack.Pop());
}
} }
[Statement("%iso", SearchMode.Contains, SpaceAround.None, ConsoleColor.Yellow, KeepStatementInArgs = true, Priority = Priority.Highest)] RuntimeInfo.IsInFunction = true;
public void CheckIfOutParameterAvalible(string args) }
{
args += " ";
args = args.Replace("%iso", (RuntimeInfo.OutParametersStack.Count > 0).ToString());
RuntimeInfo.CurrentLine = args.TrimEnd(); [Statement("in", SearchMode.StartOfLine, SpaceAround.End, ConsoleColor.Yellow)]
public void AddInParameter(string args)
{
RuntimeInfo.InParametersStack.Push(args);
}
[Statement("out", SearchMode.StartOfLine, SpaceAround.End, ConsoleColor.Yellow)]
public void GetOutParameter(string args)
{
if (RuntimeInfo.OutParametersStack.Count == 0)
{
RuntimeInfo.Exit("No out argument in stack", true);
return;
} }
[Statement("cal", SearchMode.StartOfLine, SpaceAround.End, ConsoleColor.DarkYellow, Priority = Priority.Low, Seperator = "|")] if (RuntimeInfo.Variables.ContainsKey(args))
public void Call(string args)
{ {
string[] parts = args.Split('|'); RuntimeInfo.Variables[args] = RuntimeInfo.OutParametersStack.Pop();
if (parts.Length != 2)
{
RuntimeInfo.Exit("Invalid syntax", true);
return;
}
string key = parts[0].Trim();
string[] functionArgumets = parts[1].Split(',');
foreach (string argumanet in functionArgumets)
{
RuntimeInfo.InParametersStack.Push(argumanet.Trim());
}
RuntimeInfo.FunctionCallStack.Push(new FunctionScope(RuntimeInfo.LineNumber, new Stack<string>(RuntimeInfo.InParametersStack)));
RuntimeInfo.InParametersStack.Clear();
RuntimeInfo.CurrentLine = string.Empty;
if (RuntimeInfo.Functions.ContainsKey(key))
{
RuntimeInfo.LineNumber = RuntimeInfo.Functions[key];
}
else
{
RuntimeInfo.SearchFunction = key;
}
} }
else
[Statement("get", SearchMode.StartOfLine, SpaceAround.End, ConsoleColor.Yellow)]
public void GetInParameter(string args)
{ {
if (!RuntimeInfo.IsInFunction) RuntimeInfo.Variables.Add(args, RuntimeInfo.OutParametersStack.Pop());
{
RuntimeInfo.Exit("Statement not allowed outside of function", true);
return;
}
if (RuntimeInfo.FunctionCallStack.Peek().Arguemtns.Count == 0)
{
RuntimeInfo.Exit("No in argument in stack", true);
return;
}
if (RuntimeInfo.Variables.ContainsKey(args))
{
RuntimeInfo.Variables[args] = RuntimeInfo.FunctionCallStack.Peek().Arguemtns.Pop();
}
else
{
RuntimeInfo.Variables.Add(args, RuntimeInfo.FunctionCallStack.Peek().Arguemtns.Pop());
}
}
[Statement("%isi", SearchMode.Contains, SpaceAround.End, ConsoleColor.Yellow, KeepStatementInArgs = true, Priority = Priority.Highest)]
public void CheckIfInParameterAvalible(string args)
{
if (!RuntimeInfo.IsInFunction)
{
RuntimeInfo.Exit("Statement not allowed outside of function", true);
return;
}
args += " ";
args = args.Replace("%isi", (RuntimeInfo.FunctionCallStack.Peek().Arguemtns.Count > 0).ToString());
RuntimeInfo.CurrentLine = args.TrimEnd();
}
[Statement("put", SearchMode.StartOfLine, SpaceAround.End, ConsoleColor.Yellow)]
public void AddOutParameter(string args)
{
if (!RuntimeInfo.IsInFunction)
{
RuntimeInfo.Exit("Statement not allowed outside of function", true);
return;
}
RuntimeInfo.FunctionCallStack.Peek().Results.Push(args);
}
[Statement("ret", SearchMode.Exact, SpaceAround.None, ConsoleColor.DarkYellow, ExecuteInSearchMode = true)]
public void Return(string _)
{
if (!RuntimeInfo.IsInFunction)
{
RuntimeInfo.Exit("Statement not allowed outside of function", true);
return;
}
if (RuntimeInfo.IsSearching)
{
RuntimeInfo.IsInFunction = false;
if (RuntimeInfo.IsLocalSearch)
{
RuntimeInfo.Exit($"Label \"{RuntimeInfo.SearchLabel}\" not found", true);
}
return;
}
else
{
RuntimeInfo.IsInFunction = false;
}
if (RuntimeInfo.FunctionCallStack.Count > 0)
{
FunctionScope functionScope = RuntimeInfo.FunctionCallStack.Pop();
RuntimeInfo.OutParametersStack = new Stack<string>(functionScope.Results);
RuntimeInfo.LineNumber = functionScope.CallerLine;
}
else
{
RuntimeInfo.Exit("No function in stack", true);
}
}
[Statement("ccs", SearchMode.Exact, SpaceAround.None, ConsoleColor.Red)]
public void ClearCallStack(string _)
{
RuntimeInfo.FunctionCallStack.Clear();
} }
} }
[Statement("%iso", SearchMode.Contains, SpaceAround.None, ConsoleColor.Yellow, KeepStatementInArgs = true, Priority = Priority.Highest)]
public void CheckIfOutParameterAvailable(string args)
{
args += " ";
args = args.Replace("%iso", (RuntimeInfo.OutParametersStack.Count > 0).ToString());
RuntimeInfo.CurrentLine = args.TrimEnd();
}
[Statement("cal", SearchMode.StartOfLine, SpaceAround.End, ConsoleColor.DarkYellow, Priority = Priority.Low, Separator = "|")]
public void Call(string args)
{
string[] parts = args.Split('|');
if (parts.Length != 2)
{
RuntimeInfo.Exit("Invalid syntax", true);
return;
}
string key = parts[0].Trim();
string[] functionArguments = parts[1].Split(',');
foreach (string argument in functionArguments)
{
RuntimeInfo.InParametersStack.Push(argument.Trim());
}
RuntimeInfo.FunctionCallStack.Push(new FunctionScope(RuntimeInfo.LineNumber, new Stack<string>(RuntimeInfo.InParametersStack)));
RuntimeInfo.InParametersStack.Clear();
RuntimeInfo.CurrentLine = string.Empty;
if (RuntimeInfo.Functions.TryGetValue(key, out int value))
{
RuntimeInfo.LineNumber = value;
}
else
{
RuntimeInfo.SearchFunction = key;
}
}
[Statement("get", SearchMode.StartOfLine, SpaceAround.End, ConsoleColor.Yellow)]
public void GetInParameter(string args)
{
if (!RuntimeInfo.IsInFunction)
{
RuntimeInfo.Exit("Statement not allowed outside of function", true);
return;
}
if (RuntimeInfo.FunctionCallStack.Peek().Arguments.Count == 0)
{
RuntimeInfo.Exit("No in argument in stack", true);
return;
}
if (RuntimeInfo.Variables.ContainsKey(args))
{
RuntimeInfo.Variables[args] = RuntimeInfo.FunctionCallStack.Peek().Arguments.Pop();
}
else
{
RuntimeInfo.Variables.Add(args, RuntimeInfo.FunctionCallStack.Peek().Arguments.Pop());
}
}
[Statement("%isi", SearchMode.Contains, SpaceAround.End, ConsoleColor.Yellow, KeepStatementInArgs = true, Priority = Priority.Highest)]
public void CheckIfInParameterAvailable(string args)
{
if (!RuntimeInfo.IsInFunction)
{
RuntimeInfo.Exit("Statement not allowed outside of function", true);
return;
}
args += " ";
args = args.Replace("%isi", (RuntimeInfo.FunctionCallStack.Peek().Arguments.Count > 0).ToString());
RuntimeInfo.CurrentLine = args.TrimEnd();
}
[Statement("put", SearchMode.StartOfLine, SpaceAround.End, ConsoleColor.Yellow)]
public void AddOutParameter(string args)
{
if (!RuntimeInfo.IsInFunction)
{
RuntimeInfo.Exit("Statement not allowed outside of function", true);
return;
}
RuntimeInfo.FunctionCallStack.Peek().Results.Push(args);
}
[Statement("ret", SearchMode.Exact, SpaceAround.None, ConsoleColor.DarkYellow, ExecuteInSearchMode = true)]
public void Return(string _)
{
if (!RuntimeInfo.IsInFunction)
{
RuntimeInfo.Exit("Statement not allowed outside of function", true);
return;
}
if (RuntimeInfo.IsSearching)
{
RuntimeInfo.IsInFunction = false;
if (RuntimeInfo.IsLocalSearch)
{
RuntimeInfo.Exit($"Label \"{RuntimeInfo.SearchLabel}\" not found", true);
}
return;
}
else
{
RuntimeInfo.IsInFunction = false;
}
if (RuntimeInfo.FunctionCallStack.Count > 0)
{
FunctionScope functionScope = RuntimeInfo.FunctionCallStack.Pop();
RuntimeInfo.OutParametersStack = new Stack<string>(functionScope.Results);
RuntimeInfo.LineNumber = functionScope.CallerLine;
}
else
{
RuntimeInfo.Exit("No function in stack", true);
}
}
[Statement("ccs", SearchMode.Exact, SpaceAround.None, ConsoleColor.Red)]
public void ClearCallStack(string _)
{
RuntimeInfo.FunctionCallStack.Clear();
}
} }
@@ -5,61 +5,60 @@ 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 class PredefinedVariableStatements : StatementRuntimeInformation
{ {
internal class PredifinedVariableStatements : StatementRuntimeInformation private readonly Random random = new Random();
[Statement("%time", SearchMode.Contains, SpaceAround.None, ConsoleColor.Blue, KeepStatementInArgs = true, Priority = Priority.Highest)]
public void GetUnixTimestamp(string args)
{ {
private readonly Random random = new Random(); args = args.Replace("%time", DateTimeOffset.Now.ToUnixTimeSeconds().ToString());
[Statement("%time", SearchMode.Contains, SpaceAround.None, ConsoleColor.Blue, KeepStatementInArgs = true, Priority = Priority.Highest)] RuntimeInfo.CurrentLine = args.TrimEnd();
public void GetUnixTimestamp(string args) }
[Statement("%os", SearchMode.Contains, SpaceAround.None, ConsoleColor.Blue, KeepStatementInArgs = true, Priority = Priority.Highest)]
public void GetOperatingSystem(string args)
{
args = args.Replace("%os", Environment.OSVersion.Platform.ToString());
RuntimeInfo.CurrentLine = args.TrimEnd();
}
[Statement("%cpu", SearchMode.Contains, SpaceAround.None, ConsoleColor.Blue, KeepStatementInArgs = true, Priority = Priority.Highest)]
public void GetProcessorArchitecture(string args)
{
args = args.Replace("%cpu", System.Runtime.InteropServices.RuntimeInformation.ProcessArchitecture.ToString());
RuntimeInfo.CurrentLine = args.TrimEnd();
}
[Statement("%is64", SearchMode.Contains, SpaceAround.None, ConsoleColor.Blue, KeepStatementInArgs = true, Priority = Priority.Highest)]
public void GetIsOperatingSystem64Bit(string args)
{
args = args.Replace("%is64", $"{Environment.Is64BitOperatingSystem}");
RuntimeInfo.CurrentLine = args.TrimEnd();
}
[Statement("%pi", SearchMode.Contains, SpaceAround.None, ConsoleColor.Blue, KeepStatementInArgs = true, Priority = Priority.Highest)]
public void GetPi(string args)
{
args = args.Replace("%pi", Math.PI.ToString());
RuntimeInfo.CurrentLine = args.TrimEnd();
}
[Statement("%rnd", SearchMode.Contains, SpaceAround.None, ConsoleColor.Blue, KeepStatementInArgs = true, Priority = Priority.Highest)]
public void GetRandom(string args)
{
while (args.Contains("%rnd"))
{ {
args = args.Replace("%time", DateTimeOffset.Now.ToUnixTimeSeconds().ToString()); args = args.ReplaceFirstOccurrence("%rnd", random.Next(32767, int.MaxValue).ToString());
RuntimeInfo.CurrentLine = args.TrimEnd();
} }
[Statement("%os", SearchMode.Contains, SpaceAround.None, ConsoleColor.Blue, KeepStatementInArgs = true, Priority = Priority.Highest)] RuntimeInfo.CurrentLine = args.TrimEnd();
public void GetOperatingSystem(string args)
{
args = args.Replace("%os", Environment.OSVersion.Platform.ToString());
RuntimeInfo.CurrentLine = args.TrimEnd();
}
[Statement("%cpu", SearchMode.Contains, SpaceAround.None, ConsoleColor.Blue, KeepStatementInArgs = true, Priority = Priority.Highest)]
public void GetProcessorArchitecture(string args)
{
args = args.Replace("%cpu", System.Runtime.InteropServices.RuntimeInformation.ProcessArchitecture.ToString());
RuntimeInfo.CurrentLine = args.TrimEnd();
}
[Statement("%is64", SearchMode.Contains, SpaceAround.None, ConsoleColor.Blue, KeepStatementInArgs = true, Priority = Priority.Highest)]
public void GetIsOperatingSystem64Bit(string args)
{
args = args.Replace("%is64", $"{Environment.Is64BitOperatingSystem}");
RuntimeInfo.CurrentLine = args.TrimEnd();
}
[Statement("%pi", SearchMode.Contains, SpaceAround.None, ConsoleColor.Blue, KeepStatementInArgs = true, Priority = Priority.Highest)]
public void GetPi(string args)
{
args = args.Replace("%pi", Math.PI.ToString());
RuntimeInfo.CurrentLine = args.TrimEnd();
}
[Statement("%rnd", SearchMode.Contains, SpaceAround.None, ConsoleColor.Blue, KeepStatementInArgs = true, Priority = Priority.Highest)]
public void GetRandom(string args)
{
while (args.Contains("%rnd"))
{
args = args.ReplaceFirstOccurrence("%rnd", random.Next(32767, int.MaxValue).ToString());
}
RuntimeInfo.CurrentLine = args.TrimEnd();
}
} }
} }
@@ -41,17 +41,17 @@ internal partial class ProcessingStatements : StatementRuntimeInformation
[Statement("!task", SearchMode.EndOfLine, SpaceAround.Start, ConsoleColor.DarkYellow, Priority = Priority.VeryHigh)] [Statement("!task", SearchMode.EndOfLine, SpaceAround.Start, ConsoleColor.DarkYellow, Priority = Priority.VeryHigh)]
public void RunTask(string line) public void RunTask(string line)
{ {
int lineNumer = RuntimeInfo.LineNumber; int lineNumber = RuntimeInfo.LineNumber;
List<Line> lines = RuntimeInfo.Lines.GetRange(0, RuntimeInfo.Lines.Count); List<Line> lines = RuntimeInfo.Lines.GetRange(0, RuntimeInfo.Lines.Count);
Line oldLine = lines[lineNumer]; Line oldLine = lines[lineNumber];
lines[lineNumer] = new Line(line, oldLine.FileName, oldLine.LineNumber); lines[lineNumber] = new Line(line, oldLine.FileName, oldLine.LineNumber);
_ = Task.Run(() => _ = Task.Run(() =>
{ {
YesNtInterpreter interpreter = new YesNtInterpreter(); YesNtInterpreter interpreter = new YesNtInterpreter();
interpreter.Initialize(); interpreter.Initialize();
interpreter.Execute(lines, RuntimeInfo.GloablVariables, lineNumer, RuntimeInfo); interpreter.Execute(lines, RuntimeInfo.GlobalVariables, lineNumber, RuntimeInfo);
}); });
RuntimeInfo.CurrentLine = string.Empty; RuntimeInfo.CurrentLine = string.Empty;
@@ -9,105 +9,104 @@ 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 class SystemStatements : StatementRuntimeInformation
{ {
internal class SystemStatements : StatementRuntimeInformation [Statement("exc", SearchMode.StartOfLine, SpaceAround.End, ConsoleColor.Magenta, Priority = Priority.Low, Separator = "|")]
public void ExecuteProgramWithArgs(string input)
{ {
[Statement("exc", SearchMode.StartOfLine, SpaceAround.End, ConsoleColor.Magenta, Priority = Priority.Low, Seperator = "|")] string[] parts = input.FromSafeString().Split('|');
public void ExecuteProgramWithArgs(string input) parts[0] = parts[0].Trim();
string[] functionArguments = parts[1].Split(',');
foreach (string argument in functionArguments)
{ {
string[] parts = input.FromSafeString().Split('|'); RuntimeInfo.InParametersStack.Push(argument.Trim());
parts[0] = parts[0].Trim();
string[] functionArgumets = parts[1].Split(',');
foreach (string argumanet in functionArgumets)
{
RuntimeInfo.InParametersStack.Push(argumanet.Trim());
}
try
{
StartProcess(parts[0], string.Join(string.Empty, RuntimeInfo.InParametersStack.Reverse()));
}
catch (FileNotFoundException)
{
RuntimeInfo.Exit($"Cannot find file \"{parts[0]}\".", false);
}
catch (Win32Exception ex)
{
RuntimeInfo.Exit($"Failed to start \"{parts[0]}\". {ex.Message}", false);
}
//HACK: Clear line to avoid execution from other "exc" statement
RuntimeInfo.CurrentLine = string.Empty;
} }
[Statement("exc", SearchMode.StartOfLine, SpaceAround.End, ConsoleColor.Magenta, Priority = Priority.VeryLow)] try
public void ExecuteProgram(string input)
{ {
try StartProcess(parts[0], string.Join(string.Empty, RuntimeInfo.InParametersStack.Reverse()));
{ }
StartProcess(input, string.Join(string.Empty, RuntimeInfo.InParametersStack.Reverse())); catch (FileNotFoundException)
} {
catch (FileNotFoundException) RuntimeInfo.Exit($"Cannot find file \"{parts[0]}\".", false);
{ }
RuntimeInfo.Exit($"Cannot find file \"{input}\".", false); catch (Win32Exception ex)
} {
catch (Win32Exception ex) RuntimeInfo.Exit($"Failed to start \"{parts[0]}\". {ex.Message}", false);
{
RuntimeInfo.Exit($"Failed to start \"{input}\". {ex.Message}", false);
}
} }
private void StartProcess(string name, string args) //HACK: Clear line to avoid execution from other "exc" statement
RuntimeInfo.CurrentLine = string.Empty;
}
[Statement("exc", SearchMode.StartOfLine, SpaceAround.End, ConsoleColor.Magenta, Priority = Priority.VeryLow)]
public void ExecuteProgram(string input)
{
try
{ {
RuntimeInfo.OutParametersStack.Clear(); StartProcess(input, string.Join(string.Empty, RuntimeInfo.InParametersStack.Reverse()));
FixedProcess process = new FixedProcess
{
StartInfo = new ProcessStartInfo()
{
FileName = name,
Arguments = args,
RedirectStandardOutput = true,
RedirectStandardError = true
}
};
process.OutputDataReceived += Process_OutputDataReceived;
process.ErrorDataReceived += Process_ErrorDataReceived;
_ = process.Start();
process.BeginOutputReadLine();
process.BeginErrorReadLine();
process.WaitForExit();
RuntimeInfo.InParametersStack.Clear();
RuntimeInfo.OutParametersStack.Push(process.ExitCode.ToString());
} }
catch (FileNotFoundException)
private void Process_ErrorDataReceived(object sender, Utilities.DataReceivedEventArgs e)
{ {
if (string.IsNullOrWhiteSpace(e.Data)) RuntimeInfo.Exit($"Cannot find file \"{input}\".", false);
{
return;
}
RuntimeInfo.OutParametersStack.Push(e.Data);
Console.Write("Error: " + e.Data);
} }
catch (Win32Exception ex)
private void Process_OutputDataReceived(object sender, Utilities.DataReceivedEventArgs e)
{ {
if (string.IsNullOrWhiteSpace(e.Data)) RuntimeInfo.Exit($"Failed to start \"{input}\". {ex.Message}", false);
{
return;
}
RuntimeInfo.OutParametersStack.Push(e.Data);
Console.Write(e.Data);
} }
} }
private void StartProcess(string name, string args)
{
RuntimeInfo.OutParametersStack.Clear();
FixedProcess process = new FixedProcess
{
StartInfo = new ProcessStartInfo()
{
FileName = name,
Arguments = args,
RedirectStandardOutput = true,
RedirectStandardError = true
}
};
process.OutputDataReceived += Process_OutputDataReceived;
process.ErrorDataReceived += Process_ErrorDataReceived;
_ = process.Start();
process.BeginOutputReadLine();
process.BeginErrorReadLine();
process.WaitForExit();
RuntimeInfo.InParametersStack.Clear();
RuntimeInfo.OutParametersStack.Push(process.ExitCode.ToString());
}
private void Process_ErrorDataReceived(object sender, Utilities.DataReceivedEventArgs e)
{
if (string.IsNullOrWhiteSpace(e.Data))
{
return;
}
RuntimeInfo.OutParametersStack.Push(e.Data);
Console.Write("Error: " + e.Data);
}
private void Process_OutputDataReceived(object sender, Utilities.DataReceivedEventArgs e)
{
if (string.IsNullOrWhiteSpace(e.Data))
{
return;
}
RuntimeInfo.OutParametersStack.Push(e.Data);
Console.Write(e.Data);
}
} }
@@ -47,13 +47,13 @@ internal partial class VariableStatements : StatementRuntimeInformation
RuntimeInfo.Exit("Invalid Syntax", true); RuntimeInfo.Exit("Invalid Syntax", true);
} }
if (RuntimeInfo.GloablVariables.ContainsKey(key)) if (RuntimeInfo.GlobalVariables.ContainsKey(key))
{ {
RuntimeInfo.GloablVariables[key] = parts[1].Trim(); RuntimeInfo.GlobalVariables[key] = parts[1].Trim();
} }
else else
{ {
RuntimeInfo.GloablVariables.Add(key, parts[1].Trim()); RuntimeInfo.GlobalVariables.Add(key, parts[1].Trim());
} }
} }
else else
@@ -71,9 +71,9 @@ internal partial class VariableStatements : StatementRuntimeInformation
{ {
_ = RuntimeInfo.Variables.Remove(key); _ = RuntimeInfo.Variables.Remove(key);
} }
else if (RuntimeInfo.GloablVariables.ContainsKey(key)) else if (RuntimeInfo.GlobalVariables.ContainsKey(key))
{ {
_ = RuntimeInfo.GloablVariables.Remove(key); _ = RuntimeInfo.GlobalVariables.Remove(key);
} }
else else
{ {
@@ -103,7 +103,7 @@ internal partial class VariableStatements : StatementRuntimeInformation
{ {
RuntimeInfo.CurrentLine = RuntimeInfo.CurrentLine.Replace($">{varName}", value); RuntimeInfo.CurrentLine = RuntimeInfo.CurrentLine.Replace($">{varName}", value);
} }
else if (RuntimeInfo.GloablVariables.TryGetValue(varName, out value)) else if (RuntimeInfo.GlobalVariables.TryGetValue(varName, out value))
{ {
RuntimeInfo.CurrentLine = RuntimeInfo.CurrentLine.Replace($">{varName}", value); RuntimeInfo.CurrentLine = RuntimeInfo.CurrentLine.Replace($">{varName}", value);
} }
+288 -289
View File
@@ -5,312 +5,311 @@ using System.IO;
using System.Text; using System.Text;
using System.Threading; using System.Threading;
namespace YesNt.Interpreter.Utilities namespace YesNt.Interpreter.Utilities;
public delegate void DataReceivedEventHandler(object sender, DataReceivedEventArgs e);
internal delegate void UserCallBack(string data);
public class FixedProcess : Process
{ {
internal delegate void UserCallBack(string data); public new event DataReceivedEventHandler OutputDataReceived;
public delegate void DataReceivedEventHandler(object sender, DataReceivedEventArgs e); public new event DataReceivedEventHandler ErrorDataReceived;
public class FixedProcess : Process internal AsyncStreamReader output;
internal AsyncStreamReader error;
public new void BeginOutputReadLine()
{ {
internal AsyncStreamReader output; Stream baseStream = StandardOutput.BaseStream;
internal AsyncStreamReader error; output = new AsyncStreamReader(baseStream, new UserCallBack(FixedOutputReadNotifyUser), StandardOutput.CurrentEncoding);
output.BeginReadLine();
public new event DataReceivedEventHandler OutputDataReceived;
public new event DataReceivedEventHandler ErrorDataReceived;
public new void BeginOutputReadLine()
{
Stream baseStream = StandardOutput.BaseStream;
output = new AsyncStreamReader(baseStream, new UserCallBack(FixedOutputReadNotifyUser), StandardOutput.CurrentEncoding);
output.BeginReadLine();
}
public new void BeginErrorReadLine()
{
Stream baseStream = StandardError.BaseStream;
error = new AsyncStreamReader(baseStream, new UserCallBack(FixedErrorReadNotifyUser), StandardError.CurrentEncoding);
error.BeginReadLine();
}
internal void FixedOutputReadNotifyUser(string data)
{
DataReceivedEventHandler outputDataReceived = OutputDataReceived;
if (outputDataReceived != null)
{
DataReceivedEventArgs dataReceivedEventArgs = new DataReceivedEventArgs(data);
if (SynchronizingObject != null && SynchronizingObject.InvokeRequired)
{
_ = SynchronizingObject.Invoke(outputDataReceived, new object[]
{
this,
dataReceivedEventArgs
});
return;
}
outputDataReceived(this, dataReceivedEventArgs);
}
}
internal void FixedErrorReadNotifyUser(string data)
{
DataReceivedEventHandler errorDataReceived = ErrorDataReceived;
if (errorDataReceived != null)
{
DataReceivedEventArgs dataReceivedEventArgs = new DataReceivedEventArgs(data);
if (SynchronizingObject != null && SynchronizingObject.InvokeRequired)
{
_ = SynchronizingObject.Invoke(errorDataReceived, new object[]
{
this,
dataReceivedEventArgs
});
return;
}
errorDataReceived(this, dataReceivedEventArgs);
}
}
} }
internal class AsyncStreamReader : IDisposable public new void BeginErrorReadLine()
{ {
internal const int DefaultBufferSize = 1024; Stream baseStream = StandardError.BaseStream;
private Stream stream; error = new AsyncStreamReader(baseStream, new UserCallBack(FixedErrorReadNotifyUser), StandardError.CurrentEncoding);
private Encoding encoding; error.BeginReadLine();
private Decoder decoder; }
private byte[] byteBuffer;
private char[] charBuffer;
private UserCallBack userCallBack;
private bool cancelOperation;
private ManualResetEvent eofEvent;
private readonly Queue messageQueue;
private StringBuilder sb;
private bool bLastCarriageReturn;
public virtual Encoding CurrentEncoding => encoding;
public virtual Stream BaseStream => stream;
internal AsyncStreamReader(Stream stream, UserCallBack callback, Encoding encoding) : this(stream, callback, encoding, 1024) internal void FixedOutputReadNotifyUser(string data)
{
DataReceivedEventHandler outputDataReceived = OutputDataReceived;
if (outputDataReceived != null)
{ {
} DataReceivedEventArgs dataReceivedEventArgs = new DataReceivedEventArgs(data);
if (SynchronizingObject != null && SynchronizingObject.InvokeRequired)
internal AsyncStreamReader(Stream stream, UserCallBack callback, Encoding encoding, int bufferSize)
{
Init(stream, callback, encoding, bufferSize);
messageQueue = new Queue();
}
private void Init(Stream stream, UserCallBack callback, Encoding encoding, int bufferSize)
{
this.stream = stream;
this.encoding = encoding;
userCallBack = callback;
decoder = encoding.GetDecoder();
if (bufferSize < 128)
{ {
bufferSize = 128; _ = SynchronizingObject.Invoke(outputDataReceived,
} [
byteBuffer = new byte[bufferSize]; this,
int _maxCharsPerBuffer = encoding.GetMaxCharCount(bufferSize); dataReceivedEventArgs
charBuffer = new char[_maxCharsPerBuffer]; ]);
cancelOperation = false;
eofEvent = new ManualResetEvent(false);
sb = null;
bLastCarriageReturn = false;
}
public virtual void Close()
{
Dispose(true);
}
public void Dispose()
{
Dispose(true);
GC.SuppressFinalize(this);
}
protected virtual void Dispose(bool disposing)
{
if (disposing && stream != null)
{
stream.Close();
}
if (stream != null)
{
stream = null;
encoding = null;
decoder = null;
byteBuffer = null;
charBuffer = null;
}
if (eofEvent != null)
{
eofEvent.Close();
eofEvent = null;
}
}
internal void BeginReadLine()
{
if (cancelOperation)
{
cancelOperation = false;
}
if (sb == null)
{
sb = new StringBuilder(1024);
_ = stream.BeginRead(byteBuffer, 0, byteBuffer.Length, new AsyncCallback(ReadBuffer), null);
return; return;
} }
FlushMessageQueue(); outputDataReceived(this, dataReceivedEventArgs);
}
internal void CancelOperation()
{
cancelOperation = true;
}
private void ReadBuffer(IAsyncResult ar)
{
int num;
try
{
num = stream.EndRead(ar);
}
catch (IOException)
{
num = 0;
}
catch (OperationCanceledException)
{
num = 0;
}
if (num == 0)
{
lock (messageQueue)
{
if (sb.Length != 0)
{
messageQueue.Enqueue(sb.ToString());
sb.Length = 0;
}
messageQueue.Enqueue(null);
}
try
{
FlushMessageQueue();
return;
}
finally
{
_ = eofEvent.Set();
}
}
int chars = decoder.GetChars(byteBuffer, 0, num, charBuffer, 0);
_ = sb.Append(charBuffer, 0, chars);
GetLinesFromStringBuilder();
_ = stream.BeginRead(byteBuffer, 0, byteBuffer.Length, new AsyncCallback(ReadBuffer), null);
}
private void GetLinesFromStringBuilder()
{
int i = 0;
int num = 0;
int length = sb.Length;
if (bLastCarriageReturn && length > 0 && sb[0] == '\n')
{
i = 1;
num = 1;
bLastCarriageReturn = false;
}
while (i < length)
{
char c = sb[i];
if (c is '\r' or '\n')
{
if (c == '\r' && i + 1 < length && sb[i + 1] == '\n')
{
i++;
}
string obj = sb.ToString(num, i + 1 - num);
num = i + 1;
lock (messageQueue)
{
messageQueue.Enqueue(obj);
}
}
i++;
}
// Flush Fix: Send Whatever is left in the buffer
string endOfBuffer = sb.ToString(num, length - num);
lock (messageQueue)
{
messageQueue.Enqueue(endOfBuffer);
num = length;
}
// End Flush Fix
if (sb[length - 1] == '\r')
{
bLastCarriageReturn = true;
}
if (num < length)
{
_ = sb.Remove(0, num);
}
else
{
sb.Length = 0;
}
FlushMessageQueue();
}
private void FlushMessageQueue()
{
while (messageQueue.Count > 0)
{
lock (messageQueue)
{
if (messageQueue.Count > 0)
{
string data = (string)messageQueue.Dequeue();
if (!cancelOperation)
{
userCallBack(data);
}
}
}
}
}
internal void WaitUtilEOF()
{
if (eofEvent != null)
{
_ = eofEvent.WaitOne();
eofEvent.Close();
eofEvent = null;
}
} }
} }
public class DataReceivedEventArgs : EventArgs internal void FixedErrorReadNotifyUser(string data)
{ {
internal string _data; DataReceivedEventHandler errorDataReceived = ErrorDataReceived;
if (errorDataReceived != null)
/// <summary>Gets the line of characters that was written to a redirected <see cref="T:System.Diagnostics.Process" /> output stream.</summary>
/// <returns>The line that was written by an associated <see cref="T:System.Diagnostics.Process" /> to its redirected <see cref="P:System.Diagnostics.Process.StandardOutput" /> or <see cref="P:System.Diagnostics.Process.StandardError" /> stream.</returns>
/// <filterpriority>2</filterpriority>
public string Data => _data;
internal DataReceivedEventArgs(string data)
{ {
_data = data; DataReceivedEventArgs dataReceivedEventArgs = new DataReceivedEventArgs(data);
if (SynchronizingObject != null && SynchronizingObject.InvokeRequired)
{
_ = SynchronizingObject.Invoke(errorDataReceived,
[
this,
dataReceivedEventArgs
]);
return;
}
errorDataReceived(this, dataReceivedEventArgs);
}
}
}
public class DataReceivedEventArgs : EventArgs
{
internal string _data;
/// <summary>Gets the line of characters that was written to a redirected <see cref="T:System.Diagnostics.Process" /> output stream.</summary>
/// <returns>The line that was written by an associated <see cref="T:System.Diagnostics.Process" /> to its redirected <see cref="P:System.Diagnostics.Process.StandardOutput" /> or <see cref="P:System.Diagnostics.Process.StandardError" /> stream.</returns>
/// <filterpriority>2</filterpriority>
public string Data => _data;
internal DataReceivedEventArgs(string data)
{
_data = data;
}
}
internal class AsyncStreamReader : IDisposable
{
internal const int DefaultBufferSize = 1024;
private readonly Queue messageQueue;
private Stream stream;
private Encoding encoding;
private Decoder decoder;
private byte[] byteBuffer;
private char[] charBuffer;
private UserCallBack userCallBack;
private bool cancelOperation;
private ManualResetEvent eofEvent;
private StringBuilder sb;
private bool bLastCarriageReturn;
public virtual Encoding CurrentEncoding => encoding;
public virtual Stream BaseStream => stream;
internal AsyncStreamReader(Stream stream, UserCallBack callback, Encoding encoding) : this(stream, callback, encoding, 1024)
{
}
internal AsyncStreamReader(Stream stream, UserCallBack callback, Encoding encoding, int bufferSize)
{
Init(stream, callback, encoding, bufferSize);
messageQueue = new Queue();
}
public virtual void Close()
{
Dispose(true);
}
public void Dispose()
{
Dispose(true);
GC.SuppressFinalize(this);
}
internal void BeginReadLine()
{
if (cancelOperation)
{
cancelOperation = false;
}
if (sb == null)
{
sb = new StringBuilder(1024);
_ = stream.BeginRead(byteBuffer, 0, byteBuffer.Length, new AsyncCallback(ReadBuffer), null);
return;
}
FlushMessageQueue();
}
internal void CancelOperation()
{
cancelOperation = true;
}
internal void WaitUtilEOF()
{
if (eofEvent != null)
{
_ = eofEvent.WaitOne();
eofEvent.Close();
eofEvent = null;
}
}
protected virtual void Dispose(bool disposing)
{
if (disposing && stream != null)
{
stream.Close();
}
if (stream != null)
{
stream = null;
encoding = null;
decoder = null;
byteBuffer = null;
charBuffer = null;
}
if (eofEvent != null)
{
eofEvent.Close();
eofEvent = null;
}
}
private void Init(Stream stream, UserCallBack callback, Encoding encoding, int bufferSize)
{
this.stream = stream;
this.encoding = encoding;
userCallBack = callback;
decoder = encoding.GetDecoder();
if (bufferSize < 128)
{
bufferSize = 128;
}
byteBuffer = new byte[bufferSize];
int _maxCharsPerBuffer = encoding.GetMaxCharCount(bufferSize);
charBuffer = new char[_maxCharsPerBuffer];
cancelOperation = false;
eofEvent = new ManualResetEvent(false);
sb = null;
bLastCarriageReturn = false;
}
private void ReadBuffer(IAsyncResult ar)
{
int num;
try
{
num = stream.EndRead(ar);
}
catch (IOException)
{
num = 0;
}
catch (OperationCanceledException)
{
num = 0;
}
if (num == 0)
{
lock (messageQueue)
{
if (sb.Length != 0)
{
messageQueue.Enqueue(sb.ToString());
sb.Length = 0;
}
messageQueue.Enqueue(null);
}
try
{
FlushMessageQueue();
return;
}
finally
{
_ = eofEvent.Set();
}
}
int chars = decoder.GetChars(byteBuffer, 0, num, charBuffer, 0);
_ = sb.Append(charBuffer, 0, chars);
GetLinesFromStringBuilder();
_ = stream.BeginRead(byteBuffer, 0, byteBuffer.Length, new AsyncCallback(ReadBuffer), null);
}
private void GetLinesFromStringBuilder()
{
int i = 0;
int num = 0;
int length = sb.Length;
if (bLastCarriageReturn && length > 0 && sb[0] == '\n')
{
i = 1;
num = 1;
bLastCarriageReturn = false;
}
while (i < length)
{
char c = sb[i];
if (c is '\r' or '\n')
{
if (c == '\r' && i + 1 < length && sb[i + 1] == '\n')
{
i++;
}
string obj = sb.ToString(num, i + 1 - num);
num = i + 1;
lock (messageQueue)
{
messageQueue.Enqueue(obj);
}
}
i++;
}
// Flush Fix: Send Whatever is left in the buffer
string endOfBuffer = sb.ToString(num, length - num);
lock (messageQueue)
{
messageQueue.Enqueue(endOfBuffer);
num = length;
}
// End Flush Fix
if (sb[length - 1] == '\r')
{
bLastCarriageReturn = true;
}
if (num < length)
{
_ = sb.Remove(0, num);
}
else
{
sb.Length = 0;
}
FlushMessageQueue();
}
private void FlushMessageQueue()
{
while (messageQueue.Count > 0)
{
lock (messageQueue)
{
if (messageQueue.Count > 0)
{
string data = (string)messageQueue.Dequeue();
if (!cancelOperation)
{
userCallBack(data);
}
}
}
} }
} }
} }
@@ -7,7 +7,7 @@ using System.Text;
namespace YesNt.Interpreter.Utilities; namespace YesNt.Interpreter.Utilities;
public static class StringExtentions public static class StringExtensions
{ {
private static readonly Dictionary<string, string> reverseReplacementRules; private static readonly Dictionary<string, string> reverseReplacementRules;
@@ -24,7 +24,7 @@ public static class StringExtentions
}; };
[SuppressMessage("Minor Code Smell", "S3963:\"static\" fields should be initialized inline", Justification = "Doesn't work because it throws a TypeInitializationException")] [SuppressMessage("Minor Code Smell", "S3963:\"static\" fields should be initialized inline", Justification = "Doesn't work because it throws a TypeInitializationException")]
static StringExtentions() static StringExtensions()
{ {
reverseReplacementRules = ReplacementRules.ToDictionary(x => x.Value, x => x.Key); reverseReplacementRules = ReplacementRules.ToDictionary(x => x.Value, x => x.Key);
} }
+1 -1
View File
@@ -1,7 +1,7 @@
<Project Sdk="Microsoft.NET.Sdk"> <Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup> <PropertyGroup>
<TargetFramework>net7.0</TargetFramework> <TargetFramework>net8.0</TargetFramework>
<RootNamespace>YesNt.Interpreter</RootNamespace> <RootNamespace>YesNt.Interpreter</RootNamespace>
<ApplicationIcon /> <ApplicationIcon />
<OutputType>Exe</OutputType> <OutputType>Exe</OutputType>