From 7eb53fc3c545c6bbfb4dce11be656d20ab1b253c Mon Sep 17 00:00:00 2001 From: ninemine <1371605831@qq.com> Date: Tue, 21 Oct 2025 10:26:08 +0800 Subject: [PATCH] =?UTF-8?q?=E6=96=B0=E5=A2=9E=E8=B7=B3=E8=BD=AC=E7=BC=93?= =?UTF-8?q?=E5=AD=98?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- DoRunner/JumpRuntimePointerRunner.cs | 43 +++++++++++++++++----------- RScriptContext.cs | 28 ++++++++++++++++-- RScriptEngine.cs | 5 ++++ RScriptSerializer.cs | 30 ++++++++++++++++--- 4 files changed, 83 insertions(+), 23 deletions(-) diff --git a/DoRunner/JumpRuntimePointerRunner.cs b/DoRunner/JumpRuntimePointerRunner.cs index 61cf07c..e81d607 100644 --- a/DoRunner/JumpRuntimePointerRunner.cs +++ b/DoRunner/JumpRuntimePointerRunner.cs @@ -1,5 +1,6 @@ using Convention.RScript.Parser; using System; +using System.Collections.Generic; using System.Diagnostics.CodeAnalysis; namespace Convention.RScript.Runner @@ -8,28 +9,38 @@ namespace Convention.RScript.Runner { protected static void DoJumpRuntimePointer(ExpressionParser parser, int target, RScriptContext context) { + Tuple enterKey = Tuple.Create(context.CurrentRuntimePointer, target); int currentPointer = context.CurrentRuntimePointer; - bool isForwardMove = target > context.CurrentRuntimePointer; - int step = isForwardMove ? 1 : -1; int depth = 0; int lastLayer = 0; - for (; context.CurrentRuntimePointer != target; context.CurrentRuntimePointer += step) + if (context.JumpPointerCache.TryGetValue(enterKey, out var jumpResult)) { - if (context.CurrentSentence.mode == RScriptSentence.Mode.ExitNamespace) + depth = jumpResult.Item1; + lastLayer = jumpResult.Item2; + } + else + { + bool isForwardMove = target > context.CurrentRuntimePointer; + int step = isForwardMove ? 1 : -1; + for (; context.CurrentRuntimePointer != target; context.CurrentRuntimePointer += step) { - if (isForwardMove) - lastLayer--; - else - lastLayer++; + if (context.CurrentSentence.mode == RScriptSentence.Mode.ExitNamespace) + { + if (isForwardMove) + lastLayer--; + else + lastLayer++; + } + else if (context.CurrentSentence.mode == RScriptSentence.Mode.EnterNamespace) + { + if (isForwardMove) + lastLayer++; + else + lastLayer--; + } + depth = lastLayer < depth ? lastLayer : depth; } - else if (context.CurrentSentence.mode == RScriptSentence.Mode.EnterNamespace) - { - if (isForwardMove) - lastLayer++; - else - lastLayer--; - } - depth = lastLayer < depth ? lastLayer : depth; + context.JumpPointerCache.Add(enterKey, Tuple.Create(depth, lastLayer)); } // 对上层的最深影响 for (; depth < 0; depth++) diff --git a/RScriptContext.cs b/RScriptContext.cs index 750f4c6..d6ed65a 100644 --- a/RScriptContext.cs +++ b/RScriptContext.cs @@ -92,6 +92,7 @@ namespace Convention.RScript void Run(ExpressionParser parser); IEnumerator RunAsync(ExpressionParser parser); SerializableClass Compile(ExpressionParser parser); + SerializableClass CompileFromCurrent(ExpressionParser parser); } public partial class RScriptContext : IBasicRScriptContext @@ -111,6 +112,7 @@ namespace Convention.RScript public Tuple[] NamespaceLayer; public Tuple[] NamespaceLabels; public ExpressionParser.SerializableParser CompileParser; + public Tuple, Tuple>[] JumpPointerCache; } public List SentenceParser = new() @@ -250,9 +252,14 @@ namespace Convention.RScript this.Variables.Add("context", new(typeof(object), new BuildInContext(this))); this.Sentences = data.Sentences; - this.Labels = (from item in data.Labels select item).ToDictionary(t => t.Item1, t => t.Item2); - this.NamespaceLayer = (from item in data.NamespaceLayer select item).ToDictionary(t => t.Item1, t => t.Item2); - this.NamespaceLabels = (from item in data.NamespaceLabels select item).ToDictionary(t => t.Item1, t => t.Item2); + if (data.Labels != null) + this.Labels = (from item in data.Labels select item).ToDictionary(t => t.Item1, t => t.Item2); + if (data.NamespaceLayer != null) + this.NamespaceLayer = (from item in data.NamespaceLayer select item).ToDictionary(t => t.Item1, t => t.Item2); + if (data.NamespaceLabels != null) + this.NamespaceLabels = (from item in data.NamespaceLabels select item).ToDictionary(t => t.Item1, t => t.Item2); + if (data.JumpPointerCache != null) + this.JumpPointerCache = (from item in data.JumpPointerCache select item).ToDictionary(t => t.Item1, t => t.Item2); } public RScriptSentence CurrentSentence => Sentences[CurrentRuntimePointer]; @@ -279,6 +286,7 @@ namespace Convention.RScript internal readonly Stack RuntimePointerStack = new(); internal readonly Stack GotoPointerStack = new(); + internal readonly Dictionary, Tuple> JumpPointerCache = new(); public int CurrentRuntimePointer { get; internal set; } = 0; internal readonly Stack> CurrentLocalSpaceVariableNames = new(); @@ -300,6 +308,7 @@ namespace Convention.RScript GotoPointerStack.Clear(); CurrentLocalSpaceVariableNames.Clear(); CurrentLocalSpaceVariableNames.Push(new()); + JumpPointerCache.Clear(); foreach (var staticType in Import) { parser.context.Imports.AddType(staticType); @@ -359,6 +368,19 @@ namespace Convention.RScript NamespaceLayer = (from item in NamespaceLayer select Tuple.Create(item.Key, item.Value)).ToArray(), NamespaceLabels = (from item in NamespaceLabels select Tuple.Create(item.Key, item.Value)).ToArray(), Sentences = Sentences, + JumpPointerCache = (from item in JumpPointerCache select Tuple.Create(item.Key, item.Value)).ToArray(), + }; + } + public SerializableClass CompileFromCurrent(ExpressionParser parser) + { + return new SerializableClass() + { + CompileParser = parser.Serialize(), + Labels = (from item in Labels select Tuple.Create(item.Key, item.Value)).ToArray(), + NamespaceLayer = (from item in NamespaceLayer select Tuple.Create(item.Key, item.Value)).ToArray(), + NamespaceLabels = (from item in NamespaceLabels select Tuple.Create(item.Key, item.Value)).ToArray(), + Sentences = Sentences, + JumpPointerCache = (from item in JumpPointerCache select Tuple.Create(item.Key, item.Value)).ToArray(), }; } } diff --git a/RScriptEngine.cs b/RScriptEngine.cs index 58472d8..c5d6bf3 100644 --- a/RScriptEngine.cs +++ b/RScriptEngine.cs @@ -17,6 +17,7 @@ namespace Convention.RScript Dictionary Run(string script, RScriptImportClass import = null, RScriptVariables variables = null); IEnumerator RunAsync(string script, RScriptImportClass import = null, RScriptVariables variables = null); SerializableClass Compile(string script, RScriptImportClass import = null, RScriptVariables variables = null); + SerializableClass GetCompileResultFromCurrent(); Dictionary Run(SerializableClass data, RScriptImportClass import = null, RScriptVariables variables = null); IEnumerator RunAsync(SerializableClass data, RScriptImportClass import = null, RScriptVariables variables = null); } @@ -151,6 +152,10 @@ namespace Convention.RScript context = CreateContext(SplitScript(script).ToArray(), import, variables); return context.Compile(parser); } + public SerializableClass GetCompileResultFromCurrent() + { + return context.CompileFromCurrent(parser); + } public Dictionary Run(SerializableClass data, RScriptImportClass import = null, RScriptVariables variables = null) { diff --git a/RScriptSerializer.cs b/RScriptSerializer.cs index cb7cd6e..0ab2735 100644 --- a/RScriptSerializer.cs +++ b/RScriptSerializer.cs @@ -63,8 +63,18 @@ namespace Convention.RScript } } - // 这里需要根据 ExpressionParser.SerializableParser 的结构来序列化 - // writer.Write(...); // CompileParser 的序列化 + // 序列化 JumpPointerCache 数组 + writer.Write(data.JumpPointerCache?.Length ?? 0); + if (data.JumpPointerCache != null) + { + foreach (var jpItem in data.JumpPointerCache) + { + writer.Write(jpItem.Item1.Item1); + writer.Write(jpItem.Item1.Item2); + writer.Write(jpItem.Item2.Item1); + writer.Write(jpItem.Item2.Item2); + } + } return stream.ToArray(); } @@ -141,8 +151,20 @@ namespace Convention.RScript } } - // 反序列化 CompileParser - // result.CompileParser = ...; // 根据具体结构实现 + // 反序列化 JumpPointerCache 数组 + int jumpPointerCacheLength = reader.ReadInt32(); + if (jumpPointerCacheLength > 0) + { + result.JumpPointerCache = new Tuple, Tuple>[jumpPointerCacheLength]; + for(int i=0;i