新增跳转缓存

This commit is contained in:
2025-10-21 10:26:08 +08:00
parent 58f3d1067c
commit 7eb53fc3c5
4 changed files with 83 additions and 23 deletions

View File

@@ -1,5 +1,6 @@
using Convention.RScript.Parser; using Convention.RScript.Parser;
using System; using System;
using System.Collections.Generic;
using System.Diagnostics.CodeAnalysis; using System.Diagnostics.CodeAnalysis;
namespace Convention.RScript.Runner namespace Convention.RScript.Runner
@@ -8,11 +9,19 @@ namespace Convention.RScript.Runner
{ {
protected static void DoJumpRuntimePointer(ExpressionParser parser, int target, RScriptContext context) protected static void DoJumpRuntimePointer(ExpressionParser parser, int target, RScriptContext context)
{ {
Tuple<int, int> enterKey = Tuple.Create(context.CurrentRuntimePointer, target);
int currentPointer = context.CurrentRuntimePointer; int currentPointer = context.CurrentRuntimePointer;
bool isForwardMove = target > context.CurrentRuntimePointer;
int step = isForwardMove ? 1 : -1;
int depth = 0; int depth = 0;
int lastLayer = 0; int lastLayer = 0;
if (context.JumpPointerCache.TryGetValue(enterKey, out var jumpResult))
{
depth = jumpResult.Item1;
lastLayer = jumpResult.Item2;
}
else
{
bool isForwardMove = target > context.CurrentRuntimePointer;
int step = isForwardMove ? 1 : -1;
for (; context.CurrentRuntimePointer != target; context.CurrentRuntimePointer += step) for (; context.CurrentRuntimePointer != target; context.CurrentRuntimePointer += step)
{ {
if (context.CurrentSentence.mode == RScriptSentence.Mode.ExitNamespace) if (context.CurrentSentence.mode == RScriptSentence.Mode.ExitNamespace)
@@ -31,6 +40,8 @@ namespace Convention.RScript.Runner
} }
depth = lastLayer < depth ? lastLayer : depth; depth = lastLayer < depth ? lastLayer : depth;
} }
context.JumpPointerCache.Add(enterKey, Tuple.Create(depth, lastLayer));
}
// 对上层的最深影响 // 对上层的最深影响
for (; depth < 0; depth++) for (; depth < 0; depth++)
{ {

View File

@@ -92,6 +92,7 @@ namespace Convention.RScript
void Run(ExpressionParser parser); void Run(ExpressionParser parser);
IEnumerator RunAsync(ExpressionParser parser); IEnumerator RunAsync(ExpressionParser parser);
SerializableClass Compile(ExpressionParser parser); SerializableClass Compile(ExpressionParser parser);
SerializableClass CompileFromCurrent(ExpressionParser parser);
} }
public partial class RScriptContext : IBasicRScriptContext public partial class RScriptContext : IBasicRScriptContext
@@ -111,6 +112,7 @@ namespace Convention.RScript
public Tuple<int, int>[] NamespaceLayer; public Tuple<int, int>[] NamespaceLayer;
public Tuple<string, int>[] NamespaceLabels; public Tuple<string, int>[] NamespaceLabels;
public ExpressionParser.SerializableParser CompileParser; public ExpressionParser.SerializableParser CompileParser;
public Tuple<Tuple<int, int>, Tuple<int, int>>[] JumpPointerCache;
} }
public List<IRSentenceMatcher> SentenceParser = new() public List<IRSentenceMatcher> SentenceParser = new()
@@ -250,9 +252,14 @@ namespace Convention.RScript
this.Variables.Add("context", new(typeof(object), new BuildInContext(this))); this.Variables.Add("context", new(typeof(object), new BuildInContext(this)));
this.Sentences = data.Sentences; this.Sentences = data.Sentences;
if (data.Labels != null)
this.Labels = (from item in data.Labels select item).ToDictionary(t => t.Item1, t => t.Item2); 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); 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); 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]; public RScriptSentence CurrentSentence => Sentences[CurrentRuntimePointer];
@@ -279,6 +286,7 @@ namespace Convention.RScript
internal readonly Stack<int> RuntimePointerStack = new(); internal readonly Stack<int> RuntimePointerStack = new();
internal readonly Stack<int> GotoPointerStack = new(); internal readonly Stack<int> GotoPointerStack = new();
internal readonly Dictionary<Tuple<int, int>, Tuple<int, int>> JumpPointerCache = new();
public int CurrentRuntimePointer { get; internal set; } = 0; public int CurrentRuntimePointer { get; internal set; } = 0;
internal readonly Stack<HashSet<string>> CurrentLocalSpaceVariableNames = new(); internal readonly Stack<HashSet<string>> CurrentLocalSpaceVariableNames = new();
@@ -300,6 +308,7 @@ namespace Convention.RScript
GotoPointerStack.Clear(); GotoPointerStack.Clear();
CurrentLocalSpaceVariableNames.Clear(); CurrentLocalSpaceVariableNames.Clear();
CurrentLocalSpaceVariableNames.Push(new()); CurrentLocalSpaceVariableNames.Push(new());
JumpPointerCache.Clear();
foreach (var staticType in Import) foreach (var staticType in Import)
{ {
parser.context.Imports.AddType(staticType); 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(), 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(), NamespaceLabels = (from item in NamespaceLabels select Tuple.Create(item.Key, item.Value)).ToArray(),
Sentences = Sentences, 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(),
}; };
} }
} }

View File

@@ -17,6 +17,7 @@ namespace Convention.RScript
Dictionary<string, RScriptVariableEntry> Run(string script, RScriptImportClass import = null, RScriptVariables variables = null); Dictionary<string, RScriptVariableEntry> Run(string script, RScriptImportClass import = null, RScriptVariables variables = null);
IEnumerator RunAsync(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 Compile(string script, RScriptImportClass import = null, RScriptVariables variables = null);
SerializableClass GetCompileResultFromCurrent();
Dictionary<string, RScriptVariableEntry> Run(SerializableClass data, RScriptImportClass import = null, RScriptVariables variables = null); Dictionary<string, RScriptVariableEntry> Run(SerializableClass data, RScriptImportClass import = null, RScriptVariables variables = null);
IEnumerator RunAsync(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); context = CreateContext(SplitScript(script).ToArray(), import, variables);
return context.Compile(parser); return context.Compile(parser);
} }
public SerializableClass GetCompileResultFromCurrent()
{
return context.CompileFromCurrent(parser);
}
public Dictionary<string, RScriptVariableEntry> Run(SerializableClass data, RScriptImportClass import = null, RScriptVariables variables = null) public Dictionary<string, RScriptVariableEntry> Run(SerializableClass data, RScriptImportClass import = null, RScriptVariables variables = null)
{ {

View File

@@ -63,8 +63,18 @@ namespace Convention.RScript
} }
} }
// 这里需要根据 ExpressionParser.SerializableParser 的结构来序列化 // 序列化 JumpPointerCache 数组
// writer.Write(...); // CompileParser 的序列化 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(); return stream.ToArray();
} }
@@ -141,8 +151,20 @@ namespace Convention.RScript
} }
} }
// 反序列化 CompileParser // 反序列化 JumpPointerCache 数组
// result.CompileParser = ...; // 根据具体结构实现 int jumpPointerCacheLength = reader.ReadInt32();
if (jumpPointerCacheLength > 0)
{
result.JumpPointerCache = new Tuple<Tuple<int, int>, Tuple<int, int>>[jumpPointerCacheLength];
for(int i=0;i<jumpPointerCacheLength;i++)
{
int x= reader.ReadInt32();
int y= reader.ReadInt32();
int z= reader.ReadInt32();
int w= reader.ReadInt32();
result.JumpPointerCache[i] = Tuple.Create(Tuple.Create(x, y), Tuple.Create(z, w));
}
}
return result; return result;
} }