Many improvements and bug fixes

This commit is contained in:
Stone_Red
2023-09-27 12:15:38 +02:00
parent 2e023f1a4e
commit 79df5c9b97
8 changed files with 228 additions and 213 deletions
+26 -11
View File
@@ -17,6 +17,18 @@ internal partial class SyntaxHighlighter
this.statementInformation = statementInformation; this.statementInformation = statementInformation;
} }
public static string Base64Encode(string plainText)
{
byte[] plainTextBytes = System.Text.Encoding.UTF8.GetBytes(plainText);
return System.Convert.ToBase64String(plainTextBytes);
}
public static string Base64Decode(string base64EncodedData)
{
byte[] base64EncodedBytes = System.Convert.FromBase64String(base64EncodedData);
return System.Text.Encoding.UTF8.GetString(base64EncodedBytes);
}
public void Write(string input) public void Write(string input)
{ {
input = input.Replace("\0", string.Empty); input = input.Replace("\0", string.Empty);
@@ -30,7 +42,7 @@ internal partial class SyntaxHighlighter
MatchCollection matches = EscapeSequenceRegex().Matches(input); MatchCollection matches = EscapeSequenceRegex().Matches(input);
for (int i = 0; i < matches.Count; i++) for (int i = 0; i < matches.Count; i++)
{ {
input = AddColorInformation(input, matches[i].Value, Console.ForegroundColor, SearchMode.Contains); input = AddColorInformation(input, matches[i].Value, ConsoleColor.DarkYellow, SearchMode.Contains);
} }
foreach (StatementInformation statement in statementInformation) foreach (StatementInformation statement in statementInformation)
@@ -45,9 +57,9 @@ internal partial class SyntaxHighlighter
SpaceAround.StartEnd => $" {statement.Name.Trim()} ", SpaceAround.StartEnd => $" {statement.Name.Trim()} ",
SpaceAround.Start => $" {statement.Name.Trim()}", SpaceAround.Start => $" {statement.Name.Trim()}",
SpaceAround.End => $"{statement.Name.Trim()} ", SpaceAround.End => $"{statement.Name.Trim()} ",
_ => statement.Name _ => statement.Name.Trim()
}; };
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.Seperator is not null && input.Contains(statement.Seperator))
@@ -60,7 +72,7 @@ internal partial class SyntaxHighlighter
} }
input = AddColorInformation(input, input[..name.Length], statement.Color, statement.SearchMode); input = AddColorInformation(input, input[..name.Length], statement.Color, statement.SearchMode);
} }
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.Seperator is not null && input.Contains(statement.Seperator))
{ {
@@ -70,9 +82,9 @@ internal partial class SyntaxHighlighter
{ {
continue; continue;
} }
input = AddColorInformation($"{input} ", $"{input} ".Substring($"{input} ".IndexOf(name), name.Length), statement.Color, statement.SearchMode); input = AddColorInformation(input, input.Substring(input.IndexOf(name), name.Length), statement.Color, statement.SearchMode);
} }
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.Seperator is not null && input.Contains(statement.Seperator))
{ {
@@ -84,7 +96,7 @@ internal partial class SyntaxHighlighter
} }
input = AddColorInformation(input, input[^name.Length..], statement.Color, statement.SearchMode); input = AddColorInformation(input, input[^name.Length..], statement.Color, statement.SearchMode);
} }
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.Seperator is not null && input.Contains(statement.Seperator))
{ {
@@ -126,7 +138,7 @@ internal partial class SyntaxHighlighter
bool succ = int.TryParse(stringColor, out int colorIndex); bool succ = int.TryParse(stringColor, out int colorIndex);
if (succ && colorIndex >= 0 && colorIndex < 16) if (succ && colorIndex >= 0 && colorIndex < 16)
{ {
messagePart = messagePart.Replace($"\r{stringColor}\r", string.Empty); messagePart = Base64Decode(messagePart.Replace($"\r{stringColor}\r", string.Empty));
consoleColor = (ConsoleColor)colorIndex; consoleColor = (ConsoleColor)colorIndex;
} }
else else
@@ -147,11 +159,14 @@ internal partial class SyntaxHighlighter
private static string AddColorInformation(string originalString, string value, ConsoleColor color, SearchMode searchMode) private static string AddColorInformation(string originalString, string value, ConsoleColor color, SearchMode searchMode)
{ {
int spacesAtEnd = value.WhiteSpaceAtEnd(); int spacesAtEnd = value.WhiteSpaceAtEnd();
string base64Value = Base64Encode(value.TrimEnd());
string reult = searchMode switch string reult = searchMode switch
{ {
SearchMode.StartOfLine => originalString.ReplaceFirstOccurrence(value, $"\0\r{(int)color}\r{value.TrimEnd()}\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{value.TrimEnd()}\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{value.TrimEnd()}\0" + new string(' ', spacesAtEnd)) _ => originalString.Replace(value, $"\0\r{(int)color}\r{base64Value}\0" + new string(' ', spacesAtEnd))
}; };
return reult; return reult;
} }
+3 -4
View File
@@ -1,9 +1,9 @@
using System.Collections.Generic; using System.Collections.Generic;
namespace YesNt.Interpreter.Runtime namespace YesNt.Interpreter.Runtime;
internal class FunctionScope
{ {
internal class FunctionScope
{
public int CallerLine { get; } public int CallerLine { get; }
public Dictionary<string, string> Variables { get; } = new(); public Dictionary<string, string> Variables { get; } = new();
public Dictionary<string, int> Labels { get; } = new(); public Dictionary<string, int> Labels { get; } = new();
@@ -15,5 +15,4 @@ namespace YesNt.Interpreter.Runtime
CallerLine = callerLine; CallerLine = callerLine;
Arguemtns = arguemtns; Arguemtns = arguemtns;
} }
}
} }
+17 -21
View File
@@ -1,20 +1,23 @@
using System; using System;
using System.Collections.Generic; using System.Collections.Generic;
using System.Linq;
using YesNt.Interpreter.Utilities; using YesNt.Interpreter.Utilities;
namespace YesNt.Interpreter.Runtime namespace YesNt.Interpreter.Runtime;
{
internal sealed class RuntimeInformation
{
private RuntimeInformation parentRuntimeInformation;
private static int internalTaskId = 0;
private int taskId = 0;
internal sealed class RuntimeInformation
{
public event Action<string> OnDebugOutput;
public event Action<DebugEventArgs> OnLineExecuted;
private event Action<string, bool> OnExit;
private static int internalTaskId = 0;
private readonly Dictionary<string, string> topVariables = new(); private readonly Dictionary<string, string> topVariables = new();
private readonly Dictionary<string, int> topLabels = new(); private readonly Dictionary<string, int> topLabels = new();
private RuntimeInformation parentRuntimeInformation;
private int taskId = 0;
public Dictionary<string, string> GloablVariables { get; set; } = new(); public Dictionary<string, string> GloablVariables { get; set; } = new();
public Dictionary<string, int> Functions { get; } = new(); public Dictionary<string, int> Functions { get; } = new();
public Stack<FunctionScope> FunctionCallStack { get; } = new(); public Stack<FunctionScope> FunctionCallStack { get; } = new();
@@ -59,17 +62,6 @@ namespace YesNt.Interpreter.Runtime
public bool IsSearching => !string.IsNullOrWhiteSpace(SearchLabel + SearchFunction) || (IsInFunction && FunctionCallStack.Count == 0); public bool IsSearching => !string.IsNullOrWhiteSpace(SearchLabel + SearchFunction) || (IsInFunction && FunctionCallStack.Count == 0);
public bool IsLocalSearch { get; set; } public bool IsLocalSearch { get; set; }
private event Action<string, bool> OnExit;
public event Action<string> OnDebugOutput;
public event Action<DebugEventArgs> OnLineExecuted;
private void ParentRuntimeInformation_OnExit(string exitMessage, bool stopAllTasks)
{
Exit($"Terminated by parent task", stopAllTasks);
}
public void WriteLine(string output, bool forceWrite = false) public void WriteLine(string output, bool forceWrite = false)
{ {
if ((Stop && !forceWrite) || (parentRuntimeInformation?.StopAllTasks == true && !forceWrite)) if ((Stop && !forceWrite) || (parentRuntimeInformation?.StopAllTasks == true && !forceWrite))
@@ -127,7 +119,7 @@ namespace YesNt.Interpreter.Runtime
while (FunctionCallStack.Count > 0) while (FunctionCallStack.Count > 0)
{ {
int stackLineNumber = FunctionCallStack.Pop().CallerLine; int stackLineNumber = FunctionCallStack.Pop().CallerLine;
Line stackLine = (ParentRuntimeInformation?.Lines ?? Lines).ElementAt(stackLineNumber); Line stackLine = (ParentRuntimeInformation?.Lines ?? Lines)[stackLineNumber];
WriteLine($" at line {stackLine.LineNumber + 1} in the file \"{stackLine.FileName}\"", true); WriteLine($" at line {stackLine.LineNumber + 1} in the file \"{stackLine.FileName}\"", true);
} }
@@ -177,5 +169,9 @@ namespace YesNt.Interpreter.Runtime
internalTaskId++; internalTaskId++;
#pragma warning restore S2696 // Instance members should not write to "static" fields #pragma warning restore S2696 // Instance members should not write to "static" fields
} }
private void ParentRuntimeInformation_OnExit(string exitMessage, bool stopAllTasks)
{
Exit($"Terminated by parent task", stopAllTasks);
} }
} }
+14 -14
View File
@@ -13,6 +13,10 @@ namespace YesNt.Interpreter.Runtime;
public class YesNtInterpreter public class YesNtInterpreter
{ {
public event Action<DebugEventArgs> OnLineExecuted;
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 = new();
private List<KeyValuePair<StaticStatementAttribute, Action>> staticStatements = new(); private List<KeyValuePair<StaticStatementAttribute, Action>> staticStatements = new();
@@ -38,10 +42,6 @@ public class YesNtInterpreter
} }
} }
public event Action<DebugEventArgs> OnLineExecuted;
public event Action<string> OnDebugOutput;
public void Stop() public void Stop()
{ {
runtimeInfo.Exit("Terminated by external process", true); runtimeInfo.Exit("Terminated by external process", true);
@@ -83,8 +83,13 @@ public class YesNtInterpreter
} }
} }
statements = statements.OrderBy(s => s.Key.Priority).ToDictionary(x => x.Key, x => x.Value); statements = statements
staticStatements = staticStatements.OrderBy(s => s.Key.Priority).ToList(); .OrderBy(s => s.Key.Priority)
.ThenByDescending(s => s.Key.Name.Length)
.ToDictionary(x => x.Key, x => x.Value);
staticStatements = staticStatements
.OrderBy(s => s.Key.Priority)
.ToList();
runtimeInfo.OnDebugOutput += (s) => OnDebugOutput?.Invoke(s); runtimeInfo.OnDebugOutput += (s) => OnDebugOutput?.Invoke(s);
runtimeInfo.OnLineExecuted += (DebugEventArgs e) => OnLineExecuted?.Invoke(e); runtimeInfo.OnLineExecuted += (DebugEventArgs e) => OnLineExecuted?.Invoke(e);
@@ -138,7 +143,7 @@ public class YesNtInterpreter
break; break;
} }
runtimeInfo.CurrentLine = runtimeInfo.Lines[runtimeInfo.LineNumber].Content.TrimEnd().Replace("\r", string.Empty); runtimeInfo.CurrentLine = runtimeInfo.Lines[runtimeInfo.LineNumber].Content.Trim(' ').Replace("\r", string.Empty);
if (string.IsNullOrWhiteSpace(runtimeInfo.CurrentLine) || runtimeInfo.CurrentLine.StartsWith('#')) if (string.IsNullOrWhiteSpace(runtimeInfo.CurrentLine) || runtimeInfo.CurrentLine.StartsWith('#'))
{ {
@@ -187,7 +192,7 @@ public class YesNtInterpreter
SpaceAround.StartEnd => $" {statementAttribute.Name.Trim()} ", SpaceAround.StartEnd => $" {statementAttribute.Name.Trim()} ",
SpaceAround.Start => $" {statementAttribute.Name.Trim()}", SpaceAround.Start => $" {statementAttribute.Name.Trim()}",
SpaceAround.End => $"{statementAttribute.Name.Trim()} ", SpaceAround.End => $"{statementAttribute.Name.Trim()} ",
_ => statementAttribute.Name _ => statementAttribute.Name.Trim()
}; };
if (statementAttribute.Seperator is null || runtimeInfo.CurrentLine.Contains(statementAttribute.Seperator)) if (statementAttribute.Seperator is null || runtimeInfo.CurrentLine.Contains(statementAttribute.Seperator))
@@ -198,16 +203,11 @@ public class YesNtInterpreter
statement.Value.Invoke(copyLine); statement.Value.Invoke(copyLine);
statementFound = true; statementFound = true;
} }
else if (statementAttribute.SearchMode == SearchMode.Contains && $" {runtimeInfo.CurrentLine} ".Contains(name)) else if (statementAttribute.SearchMode == SearchMode.Contains && runtimeInfo.CurrentLine.Contains(name))
{ {
bool leadingWhitespace = runtimeInfo.CurrentLine.StartsWith(' ');
runtimeInfo.CurrentLine = $" {runtimeInfo.CurrentLine} ";
string copyLine = statementAttribute.KeepStatementInArgs ? runtimeInfo.CurrentLine : runtimeInfo.CurrentLine.Replace(name, string.Empty); string copyLine = statementAttribute.KeepStatementInArgs ? runtimeInfo.CurrentLine : runtimeInfo.CurrentLine.Replace(name, string.Empty);
statement.Value.Invoke(copyLine); statement.Value.Invoke(copyLine);
statementFound = true; statementFound = true;
runtimeInfo.CurrentLine = !leadingWhitespace ? runtimeInfo.CurrentLine.Trim() : runtimeInfo.CurrentLine.TrimEnd();
} }
else if (statementAttribute.SearchMode == SearchMode.EndOfLine && runtimeInfo.CurrentLine.EndsWith(name)) else if (statementAttribute.SearchMode == SearchMode.EndOfLine && runtimeInfo.CurrentLine.EndsWith(name))
{ {
@@ -28,11 +28,11 @@ internal class ConsoleStatements : StatementRuntimeInformation
RuntimeInfo.Write(args); RuntimeInfo.Write(args);
} }
[Statement("%crl", SearchMode.Contains, SpaceAround.End, ConsoleColor.DarkGreen, KeepStatementInArgs = true, Priority = Priority.Highest)] [Statement("%crl", SearchMode.Contains, SpaceAround.None, ConsoleColor.DarkGreen, KeepStatementInArgs = true, Priority = Priority.Highest)]
public void ReadLine(string args) public void ReadLine(string args)
{ {
args += " "; args += " ";
while (args.Contains("%crl ")) while (args.Contains("%crl"))
{ {
string input = Console.ReadLine(); string input = Console.ReadLine();
if (input is null) if (input is null)
@@ -45,11 +45,11 @@ internal class ConsoleStatements : StatementRuntimeInformation
RuntimeInfo.CurrentLine = args.TrimEnd(); RuntimeInfo.CurrentLine = args.TrimEnd();
} }
[Statement("%cr", SearchMode.Contains, SpaceAround.End, ConsoleColor.DarkGreen, KeepStatementInArgs = true, Priority = Priority.Highest)] [Statement("%cr", SearchMode.Contains, SpaceAround.None, ConsoleColor.DarkGreen, KeepStatementInArgs = true, Priority = Priority.Highest)]
public void ReadKey(string args) public void ReadKey(string args)
{ {
args += " "; args += " ";
while (args.Contains("%cr ")) while (args.Contains("%cr"))
{ {
string input = ConsoleExtentions.ReadKey(RuntimeInfo).ToString(); string input = ConsoleExtentions.ReadKey(RuntimeInfo).ToString();
args = args.ReplaceFirstOccurrence("%cr ", input.ToSafeString() + " "); args = args.ReplaceFirstOccurrence("%cr ", input.ToSafeString() + " ");
@@ -81,6 +81,15 @@ internal partial class ProcessingStatements : StatementRuntimeInformation
ConsoleExtentions.Sleep(millisecondsTimeout, RuntimeInfo); ConsoleExtentions.Sleep(millisecondsTimeout, RuntimeInfo);
} }
[Statement("len", SearchMode.StartOfLine, SpaceAround.End, ConsoleColor.Magenta)]
public void Length(string args)
{
RuntimeInfo.InParametersStack.Clear();
RuntimeInfo.OutParametersStack.Clear();
RuntimeInfo.OutParametersStack.Push(args.FromSafeString().Length.ToString());
}
[Statement("imp", SearchMode.StartOfLine, SpaceAround.End, ConsoleColor.Magenta)] [Statement("imp", SearchMode.StartOfLine, SpaceAround.End, ConsoleColor.Magenta)]
public void Import(string path) public void Import(string path)
{ {
@@ -1,5 +1,4 @@
using System.Collections.Generic; using System.Text.RegularExpressions;
using System.Text.RegularExpressions;
using YesNt.Interpreter.Attributes; using YesNt.Interpreter.Attributes;
using YesNt.Interpreter.Enums; using YesNt.Interpreter.Enums;
@@ -90,27 +89,20 @@ internal partial class VariableStatements : StatementRuntimeInformation
return; return;
} }
foreach (KeyValuePair<string, string> variable in RuntimeInfo.Variables)
{
RuntimeInfo.CurrentLine = RuntimeInfo.CurrentLine.Replace($">{variable.Key}", variable.Value);
}
foreach (KeyValuePair<string, string> variable in RuntimeInfo.GloablVariables)
{
RuntimeInfo.CurrentLine = RuntimeInfo.CurrentLine.Replace($">{variable.Key}", variable.Value);
}
if (RuntimeInfo.IsSearching)
{
return;
}
MatchCollection matches = VariableStatementRegex().Matches(RuntimeInfo.CurrentLine); MatchCollection matches = VariableStatementRegex().Matches(RuntimeInfo.CurrentLine);
for (int i = 0; i < matches.Count; i++) for (int i = 0; i < matches.Count; i++)
{ {
string varName = matches[i].Value.Replace(">", string.Empty); string varName = matches[i].Value.Replace(">", string.Empty);
if (!RuntimeInfo.Variables.ContainsKey(varName) && !RuntimeInfo.GloablVariables.ContainsKey(varName)) if (RuntimeInfo.Variables.TryGetValue(varName, out string value))
{
RuntimeInfo.CurrentLine = RuntimeInfo.CurrentLine.Replace($">{varName}", value);
}
else if (RuntimeInfo.GloablVariables.TryGetValue(varName, out value))
{
RuntimeInfo.CurrentLine = RuntimeInfo.CurrentLine.Replace($">{varName}", value);
}
else if (!RuntimeInfo.IsSearching)
{ {
RuntimeInfo.Exit($"Variable \"{varName}\" not found", true); RuntimeInfo.Exit($"Variable \"{varName}\" not found", true);
return; return;
@@ -13,12 +13,16 @@ public static class StringExtentions
{ {
_ = output.Append($"\v{c}\v"); _ = output.Append($"\v{c}\v");
} }
return output.ToString(); return output
.ToString()
.Replace(' ', '~');
} }
public static string FromSafeString(this string input) public static string FromSafeString(this string input)
{ {
return input.Replace("\v", ""); return input
.Replace("\v", "")
.Replace('~', ' ');
} }
public static bool ToStandardizedNumber(this string input, out double result) public static bool ToStandardizedNumber(this string input, out double result)