diff --git a/YesNt.CodeEditor/SyntaxHighlighter.cs b/YesNt.CodeEditor/SyntaxHighlighter.cs index b69420d..7ef4d22 100644 --- a/YesNt.CodeEditor/SyntaxHighlighter.cs +++ b/YesNt.CodeEditor/SyntaxHighlighter.cs @@ -17,6 +17,18 @@ internal partial class SyntaxHighlighter 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) { input = input.Replace("\0", string.Empty); @@ -30,7 +42,7 @@ internal partial class SyntaxHighlighter MatchCollection matches = EscapeSequenceRegex().Matches(input); 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) @@ -45,9 +57,9 @@ internal partial class SyntaxHighlighter SpaceAround.StartEnd => $" {statement.Name.Trim()} ", SpaceAround.Start => $" {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.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); } - 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)) { @@ -70,9 +82,9 @@ internal partial class SyntaxHighlighter { 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)) { @@ -84,7 +96,7 @@ internal partial class SyntaxHighlighter } 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)) { @@ -126,7 +138,7 @@ internal partial class SyntaxHighlighter bool succ = int.TryParse(stringColor, out int colorIndex); 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; } else @@ -147,11 +159,14 @@ internal partial class SyntaxHighlighter private static string AddColorInformation(string originalString, string value, ConsoleColor color, SearchMode searchMode) { int spacesAtEnd = value.WhiteSpaceAtEnd(); + + string base64Value = Base64Encode(value.TrimEnd()); + string reult = searchMode switch { - SearchMode.StartOfLine => originalString.ReplaceFirstOccurrence(value, $"\0\r{(int)color}\r{value.TrimEnd()}\0" + new string(' ', spacesAtEnd)), - SearchMode.EndOfLine => originalString.ReplaceLastOccurrence(value, $"\0\r{(int)color}\r{value.TrimEnd()}\0" + new string(' ', spacesAtEnd)), - _ => originalString.Replace(value, $"\0\r{(int)color}\r{value.TrimEnd()}\0" + new string(' ', spacesAtEnd)) + 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)), + _ => originalString.Replace(value, $"\0\r{(int)color}\r{base64Value}\0" + new string(' ', spacesAtEnd)) }; return reult; } diff --git a/YesNt.Interpreter/Runtime/FunctionScope.cs b/YesNt.Interpreter/Runtime/FunctionScope.cs index ed9acf9..9b58e0c 100644 --- a/YesNt.Interpreter/Runtime/FunctionScope.cs +++ b/YesNt.Interpreter/Runtime/FunctionScope.cs @@ -1,19 +1,18 @@ using System.Collections.Generic; -namespace YesNt.Interpreter.Runtime -{ - internal class FunctionScope - { - public int CallerLine { get; } - public Dictionary Variables { get; } = new(); - public Dictionary Labels { get; } = new(); - public Stack Arguemtns { get; } - public Stack Results { get; } = new(); +namespace YesNt.Interpreter.Runtime; - public FunctionScope(int callerLine, Stack arguemtns) - { - CallerLine = callerLine; - Arguemtns = arguemtns; - } +internal class FunctionScope +{ + public int CallerLine { get; } + public Dictionary Variables { get; } = new(); + public Dictionary Labels { get; } = new(); + public Stack Arguemtns { get; } + public Stack Results { get; } = new(); + + public FunctionScope(int callerLine, Stack arguemtns) + { + CallerLine = callerLine; + Arguemtns = arguemtns; } } \ No newline at end of file diff --git a/YesNt.Interpreter/Runtime/RuntimeInformation.cs b/YesNt.Interpreter/Runtime/RuntimeInformation.cs index 2e70a69..c04e697 100644 --- a/YesNt.Interpreter/Runtime/RuntimeInformation.cs +++ b/YesNt.Interpreter/Runtime/RuntimeInformation.cs @@ -1,181 +1,177 @@ using System; using System.Collections.Generic; -using System.Linq; using YesNt.Interpreter.Utilities; -namespace YesNt.Interpreter.Runtime +namespace YesNt.Interpreter.Runtime; + +internal sealed class RuntimeInformation { - internal sealed class RuntimeInformation + public event Action OnDebugOutput; + + public event Action OnLineExecuted; + + private event Action OnExit; + + private static int internalTaskId = 0; + private readonly Dictionary topVariables = new(); + private readonly Dictionary topLabels = new(); + private RuntimeInformation parentRuntimeInformation; + private int taskId = 0; + public Dictionary GloablVariables { get; set; } = new(); + public Dictionary Functions { get; } = new(); + public Stack FunctionCallStack { get; } = new(); + public Stack InParametersStack { get; } = new(); + public Stack OutParametersStack { get; set; } = new(); + public List Lines { get; set; } = new(); + public string CurrentLine { get; set; } = string.Empty; + public string SearchLabel { get; set; } = string.Empty; + public string SearchFunction { get; set; } = string.Empty; + public int LineNumber { get; set; } = 0; + public bool Stop { get; private set; } = false; + public bool StopAllTasks { get; private set; } = false; + public bool IsDebugMode { get; set; } = false; + public string WorkingDirectory { get; set; } = string.Empty; + public bool IsTask => ParentRuntimeInformation is not null; + public int TaskId => IsTask ? taskId : 0; + public bool InternalIsInFunction { get; set; } + + public bool IsInFunction { - private RuntimeInformation parentRuntimeInformation; - private static int internalTaskId = 0; - private int taskId = 0; + get => InternalIsInFunction || FunctionCallStack.Count > 0; + set => InternalIsInFunction = value; + } - private readonly Dictionary topVariables = new(); - private readonly Dictionary topLabels = new(); + public Dictionary Variables => FunctionCallStack.Count == 0 ? topVariables : FunctionCallStack.Peek().Variables; - public Dictionary GloablVariables { get; set; } = new(); - public Dictionary Functions { get; } = new(); - public Stack FunctionCallStack { get; } = new(); - public Stack InParametersStack { get; } = new(); - public Stack OutParametersStack { get; set; } = new(); - public List Lines { get; set; } = new(); - public string CurrentLine { get; set; } = string.Empty; - public string SearchLabel { get; set; } = string.Empty; - public string SearchFunction { get; set; } = string.Empty; - public int LineNumber { get; set; } = 0; - public bool Stop { get; private set; } = false; - public bool StopAllTasks { get; private set; } = false; - public bool IsDebugMode { get; set; } = false; - public string WorkingDirectory { get; set; } = string.Empty; - public bool IsTask => ParentRuntimeInformation is not null; - public int TaskId => IsTask ? taskId : 0; - public bool InternalIsInFunction { get; set; } + public Dictionary Labels => FunctionCallStack.Count == 0 ? topLabels : FunctionCallStack.Peek().Labels; - public bool IsInFunction + public RuntimeInformation ParentRuntimeInformation + { + get => parentRuntimeInformation; + set { - get => InternalIsInFunction || FunctionCallStack.Count > 0; - set => InternalIsInFunction = value; - } - - public Dictionary Variables => FunctionCallStack.Count == 0 ? topVariables : FunctionCallStack.Peek().Variables; - - public Dictionary Labels => FunctionCallStack.Count == 0 ? topLabels : FunctionCallStack.Peek().Labels; - - public RuntimeInformation ParentRuntimeInformation - { - get => parentRuntimeInformation; - set + parentRuntimeInformation = value; + if (parentRuntimeInformation is not null) { - parentRuntimeInformation = value; - if (parentRuntimeInformation is not null) - { - parentRuntimeInformation.OnExit += ParentRuntimeInformation_OnExit; - } + parentRuntimeInformation.OnExit += ParentRuntimeInformation_OnExit; } } + } - public bool IsSearching => !string.IsNullOrWhiteSpace(SearchLabel + SearchFunction) || (IsInFunction && FunctionCallStack.Count == 0); - public bool IsLocalSearch { get; set; } + public bool IsSearching => !string.IsNullOrWhiteSpace(SearchLabel + SearchFunction) || (IsInFunction && FunctionCallStack.Count == 0); + public bool IsLocalSearch { get; set; } - private event Action OnExit; - - public event Action OnDebugOutput; - - public event Action OnLineExecuted; - - private void ParentRuntimeInformation_OnExit(string exitMessage, bool stopAllTasks) + public void WriteLine(string output, bool forceWrite = false) + { + if ((Stop && !forceWrite) || (parentRuntimeInformation?.StopAllTasks == true && !forceWrite)) { - Exit($"Terminated by parent task", stopAllTasks); + return; } - public void WriteLine(string output, bool forceWrite = false) - { - if ((Stop && !forceWrite) || (parentRuntimeInformation?.StopAllTasks == true && !forceWrite)) - { - return; - } - - if (IsDebugMode) - { - if (IsTask) - { - parentRuntimeInformation!.WriteLine(output.FromSafeString(), forceWrite); - } - else - { - OnDebugOutput?.Invoke(output.FromSafeString() + Environment.NewLine); - } - } - else - { - Console.WriteLine(output.FromSafeString()); - } - } - - public void Write(string output, bool forceWrite = false) - { - if ((Stop && !forceWrite) || (parentRuntimeInformation?.StopAllTasks == true && !forceWrite)) - { - return; - } - - if (IsDebugMode) - { - if (IsTask) - { - parentRuntimeInformation!.Write(output.FromSafeString(), forceWrite); - } - else - { - OnDebugOutput?.Invoke(output.FromSafeString()); - } - } - else - { - Console.Write(output.FromSafeString()); - } - } - - public void Exit(string message, bool stopAllTasks) - { - if (!Stop) - { - Line line = Lines[Math.Min(LineNumber, Lines.Count - 1)]; - WriteLine($"{Environment.NewLine}[{(IsTask ? $"Task {TaskId}" : "The process")} was terminated at line {line.LineNumber + 1} in the file \"{line.FileName}\" with the message: {message}]", true); - while (FunctionCallStack.Count > 0) - { - int stackLineNumber = FunctionCallStack.Pop().CallerLine; - Line stackLine = (ParentRuntimeInformation?.Lines ?? Lines).ElementAt(stackLineNumber); - WriteLine($" at line {stackLine.LineNumber + 1} in the file \"{stackLine.FileName}\"", true); - } - - Stop = true; - } - if (stopAllTasks && !StopAllTasks) - { - StopAllTasks = true; - OnExit?.Invoke(message, StopAllTasks); - parentRuntimeInformation?.Exit("Terminated by child task", true); - } - } - - public void LineExecuted(DebugEventArgs debugEventArgs) + if (IsDebugMode) { if (IsTask) { - parentRuntimeInformation.LineExecuted(debugEventArgs); + parentRuntimeInformation!.WriteLine(output.FromSafeString(), forceWrite); } else { - OnLineExecuted?.Invoke(debugEventArgs); + OnDebugOutput?.Invoke(output.FromSafeString() + Environment.NewLine); } } - - public void Reset() + else { - topVariables.Clear(); - Lines.Clear(); - GloablVariables.Clear(); - Labels.Clear(); - Functions.Clear(); - FunctionCallStack.Clear(); - ParentRuntimeInformation = null; - SearchLabel = string.Empty; - SearchFunction = string.Empty; - WorkingDirectory = string.Empty; - CurrentLine = string.Empty; - Stop = false; - StopAllTasks = false; - IsDebugMode = false; - IsInFunction = false; - IsLocalSearch = false; - LineNumber = 0; - taskId = internalTaskId + 1; -#pragma warning disable S2696 // Instance members should not write to "static" fields - internalTaskId++; -#pragma warning restore S2696 // Instance members should not write to "static" fields + Console.WriteLine(output.FromSafeString()); } } + + public void Write(string output, bool forceWrite = false) + { + if ((Stop && !forceWrite) || (parentRuntimeInformation?.StopAllTasks == true && !forceWrite)) + { + return; + } + + if (IsDebugMode) + { + if (IsTask) + { + parentRuntimeInformation!.Write(output.FromSafeString(), forceWrite); + } + else + { + OnDebugOutput?.Invoke(output.FromSafeString()); + } + } + else + { + Console.Write(output.FromSafeString()); + } + } + + public void Exit(string message, bool stopAllTasks) + { + if (!Stop) + { + Line line = Lines[Math.Min(LineNumber, Lines.Count - 1)]; + WriteLine($"{Environment.NewLine}[{(IsTask ? $"Task {TaskId}" : "The process")} was terminated at line {line.LineNumber + 1} in the file \"{line.FileName}\" with the message: {message}]", true); + while (FunctionCallStack.Count > 0) + { + int stackLineNumber = FunctionCallStack.Pop().CallerLine; + Line stackLine = (ParentRuntimeInformation?.Lines ?? Lines)[stackLineNumber]; + WriteLine($" at line {stackLine.LineNumber + 1} in the file \"{stackLine.FileName}\"", true); + } + + Stop = true; + } + if (stopAllTasks && !StopAllTasks) + { + StopAllTasks = true; + OnExit?.Invoke(message, StopAllTasks); + parentRuntimeInformation?.Exit("Terminated by child task", true); + } + } + + public void LineExecuted(DebugEventArgs debugEventArgs) + { + if (IsTask) + { + parentRuntimeInformation.LineExecuted(debugEventArgs); + } + else + { + OnLineExecuted?.Invoke(debugEventArgs); + } + } + + public void Reset() + { + topVariables.Clear(); + Lines.Clear(); + GloablVariables.Clear(); + Labels.Clear(); + Functions.Clear(); + FunctionCallStack.Clear(); + ParentRuntimeInformation = null; + SearchLabel = string.Empty; + SearchFunction = string.Empty; + WorkingDirectory = string.Empty; + CurrentLine = string.Empty; + Stop = false; + StopAllTasks = false; + IsDebugMode = false; + IsInFunction = false; + IsLocalSearch = false; + LineNumber = 0; + taskId = internalTaskId + 1; +#pragma warning disable S2696 // Instance members should not write to "static" fields + internalTaskId++; +#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); + } } \ No newline at end of file diff --git a/YesNt.Interpreter/Runtime/YesNtInterpreter.cs b/YesNt.Interpreter/Runtime/YesNtInterpreter.cs index 81974a0..d11659a 100644 --- a/YesNt.Interpreter/Runtime/YesNtInterpreter.cs +++ b/YesNt.Interpreter/Runtime/YesNtInterpreter.cs @@ -13,6 +13,10 @@ namespace YesNt.Interpreter.Runtime; public class YesNtInterpreter { + public event Action OnLineExecuted; + + public event Action OnDebugOutput; + private readonly RuntimeInformation runtimeInfo = new RuntimeInformation(); private Dictionary> statements = new(); private List> staticStatements = new(); @@ -38,10 +42,6 @@ public class YesNtInterpreter } } - public event Action OnLineExecuted; - - public event Action OnDebugOutput; - public void Stop() { 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); - staticStatements = staticStatements.OrderBy(s => s.Key.Priority).ToList(); + statements = statements + .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.OnLineExecuted += (DebugEventArgs e) => OnLineExecuted?.Invoke(e); @@ -138,7 +143,7 @@ public class YesNtInterpreter 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('#')) { @@ -187,7 +192,7 @@ public class YesNtInterpreter SpaceAround.StartEnd => $" {statementAttribute.Name.Trim()} ", SpaceAround.Start => $" {statementAttribute.Name.Trim()}", SpaceAround.End => $"{statementAttribute.Name.Trim()} ", - _ => statementAttribute.Name + _ => statementAttribute.Name.Trim() }; if (statementAttribute.Seperator is null || runtimeInfo.CurrentLine.Contains(statementAttribute.Seperator)) @@ -198,16 +203,11 @@ public class YesNtInterpreter statement.Value.Invoke(copyLine); 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); statement.Value.Invoke(copyLine); statementFound = true; - - runtimeInfo.CurrentLine = !leadingWhitespace ? runtimeInfo.CurrentLine.Trim() : runtimeInfo.CurrentLine.TrimEnd(); } else if (statementAttribute.SearchMode == SearchMode.EndOfLine && runtimeInfo.CurrentLine.EndsWith(name)) { diff --git a/YesNt.Interpreter/Statements/ConsoleStatements.cs b/YesNt.Interpreter/Statements/ConsoleStatements.cs index d0bd322..406db42 100644 --- a/YesNt.Interpreter/Statements/ConsoleStatements.cs +++ b/YesNt.Interpreter/Statements/ConsoleStatements.cs @@ -28,11 +28,11 @@ internal class ConsoleStatements : StatementRuntimeInformation 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) { args += " "; - while (args.Contains("%crl ")) + while (args.Contains("%crl")) { string input = Console.ReadLine(); if (input is null) @@ -45,11 +45,11 @@ internal class ConsoleStatements : StatementRuntimeInformation 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) { args += " "; - while (args.Contains("%cr ")) + while (args.Contains("%cr")) { string input = ConsoleExtentions.ReadKey(RuntimeInfo).ToString(); args = args.ReplaceFirstOccurrence("%cr ", input.ToSafeString() + " "); diff --git a/YesNt.Interpreter/Statements/ProcessingStatements.cs b/YesNt.Interpreter/Statements/ProcessingStatements.cs index 8c77aa8..0b5bd26 100644 --- a/YesNt.Interpreter/Statements/ProcessingStatements.cs +++ b/YesNt.Interpreter/Statements/ProcessingStatements.cs @@ -81,6 +81,15 @@ internal partial class ProcessingStatements : StatementRuntimeInformation 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)] public void Import(string path) { diff --git a/YesNt.Interpreter/Statements/VariableStatements.cs b/YesNt.Interpreter/Statements/VariableStatements.cs index 98eb57d..490512d 100644 --- a/YesNt.Interpreter/Statements/VariableStatements.cs +++ b/YesNt.Interpreter/Statements/VariableStatements.cs @@ -1,5 +1,4 @@ -using System.Collections.Generic; -using System.Text.RegularExpressions; +using System.Text.RegularExpressions; using YesNt.Interpreter.Attributes; using YesNt.Interpreter.Enums; @@ -90,27 +89,20 @@ internal partial class VariableStatements : StatementRuntimeInformation return; } - foreach (KeyValuePair variable in RuntimeInfo.Variables) - { - RuntimeInfo.CurrentLine = RuntimeInfo.CurrentLine.Replace($">{variable.Key}", variable.Value); - } - - foreach (KeyValuePair variable in RuntimeInfo.GloablVariables) - { - RuntimeInfo.CurrentLine = RuntimeInfo.CurrentLine.Replace($">{variable.Key}", variable.Value); - } - - if (RuntimeInfo.IsSearching) - { - return; - } - MatchCollection matches = VariableStatementRegex().Matches(RuntimeInfo.CurrentLine); for (int i = 0; i < matches.Count; i++) { string varName = matches[i].Value.Replace(">", string.Empty); - if (!RuntimeInfo.Variables.ContainsKey(varName) && !RuntimeInfo.GloablVariables.ContainsKey(varName)) + 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); return; diff --git a/YesNt.Interpreter/Utilities/StringExtentions.cs b/YesNt.Interpreter/Utilities/StringExtentions.cs index c7a674a..06efe5f 100644 --- a/YesNt.Interpreter/Utilities/StringExtentions.cs +++ b/YesNt.Interpreter/Utilities/StringExtentions.cs @@ -13,12 +13,16 @@ public static class StringExtentions { _ = output.Append($"\v{c}\v"); } - return output.ToString(); + return output + .ToString() + .Replace(' ', '~'); } 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)