mirror of
https://github.com/Stone-Red-Code/YesNt-Interpreter.git
synced 2026-09-09 07:56:06 +02:00
Upgrade to .NET 8 and code cleanup
This commit is contained in:
@@ -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
|
||||||
|
|||||||
@@ -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
|
||||||
|
|||||||
@@ -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": ""
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
}
|
}
|
||||||
@@ -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]+")]
|
||||||
|
|||||||
@@ -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>
|
||||||
|
|
||||||
|
|||||||
@@ -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>
|
||||||
|
|||||||
@@ -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;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
@@ -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
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
@@ -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
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
@@ -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
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
@@ -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": ""
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
}
|
}
|
||||||
@@ -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; }
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
@@ -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;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
@@ -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))
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -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);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
@@ -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);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -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,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>
|
||||||
|
|||||||
Reference in New Issue
Block a user