diff --git a/RScriptContext.cs b/RScriptContext.cs index 39ea410..ea0bf44 100644 --- a/RScriptContext.cs +++ b/RScriptContext.cs @@ -1,6 +1,7 @@ using Convention.RScript.Matcher; using Convention.RScript.Parser; using System; +using System.Collections; using System.Collections.Generic; using System.Linq; @@ -293,17 +294,13 @@ namespace Convention.RScript } } - private void RunNextStep(ExpressionParser parser) + private object RunNextStep(ExpressionParser parser) { var sentence = CurrentSentence; switch (sentence.mode) { case RScriptSentence.Mode.Expression: - { - // 执行表达式 - parser.Evaluate(sentence.content); - } - break; + return parser.Evaluate(sentence.content); case RScriptSentence.Mode.DefineVariable: { DoDefineVariable(parser, sentence); @@ -326,7 +323,7 @@ namespace Convention.RScript break; case RScriptSentence.Mode.Breakpoint: { - DoBreakpoint(parser,sentence); + DoBreakpoint(parser, sentence); } break; case RScriptSentence.Mode.Backpoint: @@ -338,6 +335,7 @@ namespace Convention.RScript // Do nothing break; } + return null; } private readonly Stack RuntimePointerStack = new(); @@ -345,7 +343,17 @@ namespace Convention.RScript private int CurrentRuntimePointer = 0; private readonly Stack> CurrentLocalSpaceVariableNames = new(); - public Dictionary Run(ExpressionParser parser) + public Dictionary GetCurrentVariables() + { + Dictionary result = new(); + foreach (var (key, value) in Variables) + { + result[key] = value; + } + return result; + } + + public void Run(ExpressionParser parser) { CurrentLocalSpaceVariableNames.Clear(); RuntimePointerStack.Clear(); @@ -362,12 +370,30 @@ namespace Convention.RScript if (Variables.ContainsKey(varName)) Variables.SetValue(varName, varValue); } - Dictionary result = new(); - foreach (var (key, value) in Variables) + } + + public IEnumerator RunAsync(ExpressionParser parser) + { + CurrentLocalSpaceVariableNames.Clear(); + RuntimePointerStack.Clear(); + GotoPointerStack.Clear(); + CurrentLocalSpaceVariableNames.Clear(); + CurrentLocalSpaceVariableNames.Push(new()); + for (CurrentRuntimePointer = 0; CurrentRuntimePointer < Sentences.Length; CurrentRuntimePointer++) { - result[key] = value; + var ret = RunNextStep(parser); + if (ret is IEnumerator ir) + { + yield return ir; + } + yield return null; + } + // 更新上下文变量 + foreach (var (varName, varValue) in parser.context.Variables) + { + if (Variables.ContainsKey(varName)) + Variables.SetValue(varName, varValue); } - return result; } } } diff --git a/RScriptEngine.cs b/RScriptEngine.cs index 7ed71ee..3862704 100644 --- a/RScriptEngine.cs +++ b/RScriptEngine.cs @@ -1,5 +1,6 @@ using Convention.RScript.Parser; using System; +using System.Collections; using System.Collections.Generic; using System.Linq; using System.Text; @@ -105,7 +106,17 @@ namespace Convention.RScript context = new(SplitScript(script).ToArray(), import, variables); foreach (var type in context.Import) parser.context.Imports.AddType(type); - return context.Run(parser); + context.Run(parser); + return context.GetCurrentVariables(); + } + + public IEnumerator RunAsync(string script, RScriptImportClass import = null, RScriptVariables variables = null) + { + parser = new(new()); + context = new(SplitScript(script).ToArray(), import, variables); + foreach (var type in context.Import) + parser.context.Imports.AddType(type); + return context.RunAsync(parser); } } }