diff --git a/YesNt.Interpreter/Runtime/FunctionScope.cs b/YesNt.Interpreter/Runtime/FunctionScope.cs index 8e91f23..65865ff 100644 --- a/YesNt.Interpreter/Runtime/FunctionScope.cs +++ b/YesNt.Interpreter/Runtime/FunctionScope.cs @@ -6,10 +6,13 @@ namespace YesNt.Interpreter.Runtime { public int CallerLine { get; } public Dictionary Variables { get; } = new(); + public Stack Arguemtns { get; } = new(); + public Stack Results { get; } = new(); - public FunctionScope(int callerLine) + 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 1447eda..95f6a7b 100644 --- a/YesNt.Interpreter/Runtime/RuntimeInformation.cs +++ b/YesNt.Interpreter/Runtime/RuntimeInformation.cs @@ -17,6 +17,8 @@ namespace YesNt.Interpreter public Dictionary Labels { get; } = 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; diff --git a/YesNt.Interpreter/Statements/CodeFlowStatements.cs b/YesNt.Interpreter/Statements/CodeFlowStatements.cs index bb01e07..55ff3ce 100644 --- a/YesNt.Interpreter/Statements/CodeFlowStatements.cs +++ b/YesNt.Interpreter/Statements/CodeFlowStatements.cs @@ -1,4 +1,6 @@ using System; +using System.Collections.Generic; +using System.Linq; using YesNt.Interpreter.Attributes; using YesNt.Interpreter.Enums; @@ -24,23 +26,6 @@ namespace YesNt.Interpreter.Statements } } - [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) { @@ -75,6 +60,43 @@ namespace YesNt.Interpreter.Statements } } + [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("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(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) { @@ -99,7 +121,8 @@ namespace YesNt.Interpreter.Statements return; } - RuntimeInfo.FunctionCallStack.Push(new FunctionScope(RuntimeInfo.LineNumber)); + RuntimeInfo.FunctionCallStack.Push(new FunctionScope(RuntimeInfo.LineNumber, new Stack(RuntimeInfo.InParametersStack.Reverse()))); + RuntimeInfo.InParametersStack.Clear(); if (RuntimeInfo.Functions.ContainsKey(key)) { @@ -111,81 +134,6 @@ namespace YesNt.Interpreter.Statements } } - [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 _) { diff --git a/YesNt.Interpreter/Statements/FunctionStatements.cs b/YesNt.Interpreter/Statements/FunctionStatements.cs new file mode 100644 index 0000000..af72c7c --- /dev/null +++ b/YesNt.Interpreter/Statements/FunctionStatements.cs @@ -0,0 +1,118 @@ +using System; + +using YesNt.Interpreter.Attributes; +using YesNt.Interpreter.Enums; +using YesNt.Interpreter.Runtime; + +namespace YesNt.Interpreter.Statements +{ + internal class FunctionStatements : StatementRuntimeInformation + { + [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("in", SearchMode.StartOfLine, SpaceAround.End, ConsoleColor.DarkYellow)] + public void AddInParameter(string args) + { + RuntimeInfo.InParametersStack.Push(args); + } + + [Statement("out", SearchMode.StartOfLine, SpaceAround.End, ConsoleColor.DarkYellow)] + public void GetOutParameter(string name) + { + if (RuntimeInfo.OutParametersStack.Count == 0) + { + RuntimeInfo.Exit("No out parameter in stack", true); + return; + } + + RuntimeInfo.Variables.Add(name, RuntimeInfo.OutParametersStack.Pop()); + } + + [Statement("get", SearchMode.StartOfLine, SpaceAround.End, ConsoleColor.DarkYellow)] + public void GetInParameter(string args) + { + if (RuntimeInfo.FunctionCallStack.Count == 0) + { + RuntimeInfo.Exit("No function in stack", true); + return; + } + + if (RuntimeInfo.FunctionCallStack.Peek().Arguemtns.Count == 0) + { + RuntimeInfo.Exit("No in parameter in stack", true); + return; + } + + RuntimeInfo.Variables.TryAdd(args, RuntimeInfo.FunctionCallStack.Peek().Arguemtns.Pop()); + } + + [Statement("put", SearchMode.StartOfLine, SpaceAround.End, ConsoleColor.DarkYellow)] + public void AddOutParameter(string args) + { + if (RuntimeInfo.FunctionCallStack.Count == 0) + { + RuntimeInfo.Exit("No function in stack", 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("Not in function", true); + return; + } + + if (RuntimeInfo.IsSearching) + { + RuntimeInfo.IsInFunction = false; + return; + } + else + { + RuntimeInfo.IsInFunction = false; + } + + if (RuntimeInfo.FunctionCallStack.Count > 0) + { + FunctionScope functionScope = RuntimeInfo.FunctionCallStack.Pop(); + + RuntimeInfo.OutParametersStack = functionScope.Results; + RuntimeInfo.LineNumber = functionScope.CallerLine; + } + else + { + RuntimeInfo.Exit("No function in stack", true); + } + } + } +} \ No newline at end of file