mirror of
https://github.com/Stone-Red-Code/YesNt-Interpreter.git
synced 2026-09-08 16:06:07 +02:00
- Add functions
- Code improvements
This commit is contained in:
@@ -0,0 +1,221 @@
|
||||
using System;
|
||||
|
||||
using YesNt.Interpreter.Attributes;
|
||||
using YesNt.Interpreter.Enums;
|
||||
using YesNt.Interpreter.Runtime;
|
||||
using YesNt.Interpreter.Utilities;
|
||||
|
||||
namespace YesNt.Interpreter.Statements
|
||||
{
|
||||
internal class CodeFlowStatements : StatementRuntimeInformation
|
||||
{
|
||||
[Statement("jmp", SearchMode.StartOfLine, SpaceAround.End, ConsoleColor.Green, Priority = Priority.VeryLow)]
|
||||
public void Jump(string args)
|
||||
{
|
||||
string key = args.Trim();
|
||||
|
||||
if (RuntimeInfo.Labels.ContainsKey(key))
|
||||
{
|
||||
RuntimeInfo.LineNumber = RuntimeInfo.Labels[key];
|
||||
}
|
||||
else
|
||||
{
|
||||
RuntimeInfo.SearchLabel = key;
|
||||
}
|
||||
}
|
||||
|
||||
[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));
|
||||
|
||||
if (RuntimeInfo.Functions.ContainsKey(key))
|
||||
{
|
||||
RuntimeInfo.LineNumber = RuntimeInfo.Functions[key];
|
||||
}
|
||||
else
|
||||
{
|
||||
RuntimeInfo.SearchFunction = key;
|
||||
}
|
||||
}
|
||||
|
||||
[Statement("jif", SearchMode.StartOfLine, SpaceAround.End, ConsoleColor.Green, Priority = Priority.VeryLow, Seperator = "|")]
|
||||
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 != true)
|
||||
{
|
||||
if (result is null)
|
||||
{
|
||||
RuntimeInfo.Exit("Invalid operation", true);
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
if (RuntimeInfo.Labels.ContainsKey(key))
|
||||
{
|
||||
RuntimeInfo.LineNumber = RuntimeInfo.Labels[key];
|
||||
}
|
||||
else
|
||||
{
|
||||
RuntimeInfo.SearchLabel = 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 != true)
|
||||
{
|
||||
if (result is null)
|
||||
{
|
||||
RuntimeInfo.Exit("Invalid operation", true);
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
RuntimeInfo.FunctionCallStack.Push(new FunctionScope(RuntimeInfo.LineNumber));
|
||||
|
||||
if (RuntimeInfo.Functions.ContainsKey(key))
|
||||
{
|
||||
RuntimeInfo.LineNumber = RuntimeInfo.Functions[key];
|
||||
}
|
||||
else
|
||||
{
|
||||
RuntimeInfo.SearchFunction = key;
|
||||
}
|
||||
}
|
||||
|
||||
[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;
|
||||
}
|
||||
}
|
||||
|
||||
[Statement("fnc", SearchMode.StartOfLine, SpaceAround.End, ConsoleColor.DarkYellow, ExecuteInSearchMode = true)]
|
||||
public void FindFunction(string args)
|
||||
{
|
||||
if (RuntimeInfo.InternalIsInFunction)
|
||||
{
|
||||
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("ret", SearchMode.Exact, SpaceAround.None, ConsoleColor.DarkYellow, ExecuteInSearchMode = true)]
|
||||
public void Return(string _)
|
||||
{
|
||||
if (!RuntimeInfo.IsInFunction)
|
||||
{
|
||||
RuntimeInfo.Exit("Not in function", true);
|
||||
return;
|
||||
}
|
||||
|
||||
if (RuntimeInfo.IsSearching)
|
||||
{
|
||||
RuntimeInfo.IsInFunction = false;
|
||||
return;
|
||||
}
|
||||
else
|
||||
{
|
||||
RuntimeInfo.IsInFunction = false;
|
||||
}
|
||||
|
||||
if (RuntimeInfo.FunctionCallStack.Count > 0)
|
||||
{
|
||||
RuntimeInfo.LineNumber = RuntimeInfo.FunctionCallStack.Pop().CallerLine;
|
||||
}
|
||||
else
|
||||
{
|
||||
RuntimeInfo.Exit("No function in stack", true);
|
||||
}
|
||||
}
|
||||
|
||||
[Statement("end", SearchMode.Exact, SpaceAround.None, ConsoleColor.Red, ExecuteInSearchMode = true)]
|
||||
public void End(string _)
|
||||
{
|
||||
if (RuntimeInfo.IsSearching)
|
||||
{
|
||||
RuntimeInfo.IsInFunction = false;
|
||||
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;
|
||||
return;
|
||||
}
|
||||
else
|
||||
{
|
||||
RuntimeInfo.IsInFunction = false;
|
||||
}
|
||||
|
||||
RuntimeInfo.Exit("Planned termination by code. Canceling all tasks", true);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,58 @@
|
||||
using System;
|
||||
|
||||
using YesNt.Interpreter.Attributes;
|
||||
using YesNt.Interpreter.Enums;
|
||||
using YesNt.Interpreter.Utilities;
|
||||
|
||||
namespace YesNt.Interpreter.Statements
|
||||
{
|
||||
internal class ConsoleStatements : StatementRuntimeInformation
|
||||
{
|
||||
[Statement("cwl", SearchMode.StartOfLine, SpaceAround.End, ConsoleColor.DarkGreen, Priority = Priority.VeryLow)]
|
||||
public void WriteLine(string args)
|
||||
{
|
||||
RuntimeInfo.WriteLine(args);
|
||||
}
|
||||
|
||||
[Statement("cw", SearchMode.StartOfLine, SpaceAround.End, ConsoleColor.DarkGreen, Priority = Priority.VeryLow)]
|
||||
public void Write(string args)
|
||||
{
|
||||
RuntimeInfo.Write(args);
|
||||
}
|
||||
|
||||
[Statement("%crl", SearchMode.Contains, SpaceAround.End, ConsoleColor.DarkGreen, KeepStatementInArgs = true, Priority = Priority.Highest)]
|
||||
public void ReadLine(string args)
|
||||
{
|
||||
args += " ";
|
||||
while (args.Contains("%crl "))
|
||||
{
|
||||
string input = Console.ReadLine();
|
||||
if (input is null)
|
||||
{
|
||||
RuntimeInfo.Exit("Terminated by external process", true);
|
||||
return;
|
||||
}
|
||||
args = args.ReplaceFirstOccurrence("%crl ", input.ToSaveString() + " ");
|
||||
}
|
||||
RuntimeInfo.CurrentLine = args.TrimEnd();
|
||||
}
|
||||
|
||||
[Statement("%cr", SearchMode.Contains, SpaceAround.End, ConsoleColor.DarkGreen, KeepStatementInArgs = true, Priority = Priority.Highest)]
|
||||
public void ReadKey(string args)
|
||||
{
|
||||
args += " ";
|
||||
while (args.Contains("%cr "))
|
||||
{
|
||||
string input = ConsoleExtentions.ReadKey(RuntimeInfo).ToString();
|
||||
args = args.ReplaceFirstOccurrence("%cr ", input.ToSaveString() + " ");
|
||||
}
|
||||
RuntimeInfo.CurrentLine = args.TrimEnd();
|
||||
}
|
||||
|
||||
[Statement("cls", SearchMode.Exact, SpaceAround.None, ConsoleColor.Magenta)]
|
||||
public void Clear(string args)
|
||||
{
|
||||
Console.Clear();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,90 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.IO;
|
||||
using System.Text.RegularExpressions;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
using YesNt.Interpreter.Attributes;
|
||||
using YesNt.Interpreter.Enums;
|
||||
using YesNt.Interpreter.Utilities;
|
||||
|
||||
namespace YesNt.Interpreter.Statements
|
||||
{
|
||||
internal class ProcessingStatements : StatementRuntimeInformation
|
||||
{
|
||||
[Statement("!calc", SearchMode.EndOfLine, SpaceAround.Start, ConsoleColor.DarkYellow, Priority = Priority.High, ExecuteInSearchMode = true)]
|
||||
public void Calculate(string args)
|
||||
{
|
||||
MatchCollection matches = Regex.Matches(args, @"((\)?)+(\(?)+[0-9]+(((\s?)+(\)?)(\s?)+\+(\s?)+(\(?)+(\s?)+|(\s?)+(\)?)(\s?)+\-(\s?)+(\(?)+(\s?)+|(\s?)+(\)?)(\s?)+\*(\s?)+(\(?)+(\s?)+|(\s?)+(\)?)(\s?)+\/(\s?)+(\(?)+(\s?)+)|[,.])(?=[0-9])+)+[0-9]+(\)?)+");
|
||||
|
||||
for (int i = 0; i < matches.Count; i++)
|
||||
{
|
||||
string res = Evaluator.Calculate(matches[i].Value);
|
||||
if (res is null)
|
||||
{
|
||||
RuntimeInfo.Exit("Invalid operation", true);
|
||||
return;
|
||||
}
|
||||
args = args.Replace(matches[0].Value, res);
|
||||
}
|
||||
|
||||
RuntimeInfo.CurrentLine = args;
|
||||
}
|
||||
|
||||
[Statement("!eval", SearchMode.EndOfLine, SpaceAround.Start, ConsoleColor.DarkYellow, Priority = Priority.VeryHigh)]
|
||||
public void Evaluate(string args)
|
||||
{
|
||||
RuntimeInfo.CurrentLine = args.FromSaveString();
|
||||
}
|
||||
|
||||
[Statement("!task", SearchMode.EndOfLine, SpaceAround.Start, ConsoleColor.DarkYellow, Priority = Priority.VeryHigh)]
|
||||
public void RunTask(string line)
|
||||
{
|
||||
int lineNumer = RuntimeInfo.LineNumber;
|
||||
List<string> lines = RuntimeInfo.Lines.GetRange(0, RuntimeInfo.Lines.Count);
|
||||
lines[lineNumer] = line;
|
||||
_ = Task.Run(() =>
|
||||
{
|
||||
YesNtInterpreter interpreter = new YesNtInterpreter();
|
||||
interpreter.Initialize();
|
||||
interpreter.Execute(lines, RuntimeInfo.GloablVariables, lineNumer, RuntimeInfo);
|
||||
});
|
||||
|
||||
RuntimeInfo.CurrentLine = string.Empty;
|
||||
}
|
||||
|
||||
[Statement("slp", SearchMode.StartOfLine, SpaceAround.End, ConsoleColor.Magenta)]
|
||||
public void Sleep(string args)
|
||||
{
|
||||
_ = int.TryParse(args, out int millisecondsTimeout);
|
||||
ConsoleExtentions.Sleep(millisecondsTimeout, RuntimeInfo);
|
||||
}
|
||||
|
||||
[Statement("imp", SearchMode.StartOfLine, SpaceAround.End, ConsoleColor.Magenta)]
|
||||
public void Import(string path)
|
||||
{
|
||||
if (string.IsNullOrEmpty(Path.GetExtension(path)))
|
||||
{
|
||||
path = Path.ChangeExtension(path, "ynt");
|
||||
}
|
||||
|
||||
if (File.Exists(path))
|
||||
{
|
||||
try
|
||||
{
|
||||
RuntimeInfo.Lines.RemoveAt(0);
|
||||
RuntimeInfo.Lines.InsertRange(RuntimeInfo.LineNumber, File.ReadAllLines(path));
|
||||
RuntimeInfo.LineNumber--;
|
||||
}
|
||||
catch
|
||||
{
|
||||
RuntimeInfo.Exit($"Could not load file {path}", true);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
RuntimeInfo.Exit($"Could not find file {path}", true);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,122 @@
|
||||
using System.Collections.Generic;
|
||||
using System.Text.RegularExpressions;
|
||||
|
||||
using YesNt.Interpreter.Attributes;
|
||||
using YesNt.Interpreter.Enums;
|
||||
|
||||
namespace YesNt.Interpreter.Statements
|
||||
{
|
||||
internal class VariableStatements : StatementRuntimeInformation
|
||||
{
|
||||
[Statement("<", SearchMode.StartOfLine, SpaceAround.None, Priority = Priority.VeryLow)]
|
||||
public void DefineVariable(string args)
|
||||
{
|
||||
string[] parts = args.Split('=');
|
||||
if (parts.Length == 2)
|
||||
{
|
||||
string key = parts[0].Trim();
|
||||
if (key.Contains(' '))
|
||||
{
|
||||
RuntimeInfo.Exit("Invalid Syntax", true);
|
||||
}
|
||||
|
||||
if (RuntimeInfo.Variables.ContainsKey(key))
|
||||
{
|
||||
RuntimeInfo.Variables[key] = parts[1].Trim();
|
||||
}
|
||||
else
|
||||
{
|
||||
RuntimeInfo.Variables.Add(key, parts[1].Trim());
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
RuntimeInfo.Exit("Invalid syntax", true);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
[Statement("!<", SearchMode.StartOfLine, SpaceAround.None, Priority = Priority.VeryLow)]
|
||||
public void DefineGlobalVariable(string args)
|
||||
{
|
||||
string[] parts = args.Split('=');
|
||||
if (parts.Length == 2)
|
||||
{
|
||||
string key = parts[0].Trim();
|
||||
if (key.Contains(' '))
|
||||
{
|
||||
RuntimeInfo.Exit("Invalid Syntax", true);
|
||||
}
|
||||
|
||||
if (RuntimeInfo.GloablVariables.ContainsKey(key))
|
||||
{
|
||||
RuntimeInfo.GloablVariables[key] = parts[1].Trim();
|
||||
}
|
||||
else
|
||||
{
|
||||
RuntimeInfo.GloablVariables.Add(key, parts[1].Trim());
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
RuntimeInfo.Exit("Invalid syntax", true);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
[Statement("del", SearchMode.StartOfLine, SpaceAround.End, System.ConsoleColor.Red, Priority = Priority.VeryLow)]
|
||||
public void DeleteVariable(string args)
|
||||
{
|
||||
string key = args.Trim();
|
||||
|
||||
if (RuntimeInfo.Variables.ContainsKey(key))
|
||||
{
|
||||
RuntimeInfo.Variables.Remove(key);
|
||||
}
|
||||
else if (RuntimeInfo.GloablVariables.ContainsKey(key))
|
||||
{
|
||||
RuntimeInfo.GloablVariables.Remove(key);
|
||||
}
|
||||
else
|
||||
{
|
||||
RuntimeInfo.Exit($"Variable \"{key}\" not found", true);
|
||||
}
|
||||
}
|
||||
|
||||
[StaticStatement(ExecuteInSearchLabelMode = true)]
|
||||
public void ReadVariable()
|
||||
{
|
||||
if (!RuntimeInfo.CurrentLine.Contains('>'))
|
||||
{
|
||||
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 = Regex.Matches(RuntimeInfo.CurrentLine, @">[a-zA-Z0-9]+");
|
||||
|
||||
for (int i = 0; i < matches.Count; i++)
|
||||
{
|
||||
string varName = matches[i].Value.Replace(">", string.Empty);
|
||||
if (!RuntimeInfo.Variables.ContainsKey(varName) && !RuntimeInfo.GloablVariables.ContainsKey(varName))
|
||||
{
|
||||
RuntimeInfo.Exit($"Variable \"{varName}\" not found", true);
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user