Compare commits
2 Commits
7b48066aaf
...
7eb53fc3c5
Author | SHA1 | Date | |
---|---|---|---|
7eb53fc3c5 | |||
58f3d1067c |
@@ -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<int, int> 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++)
|
||||
|
@@ -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<int, int>[] NamespaceLayer;
|
||||
public Tuple<string, int>[] NamespaceLabels;
|
||||
public ExpressionParser.SerializableParser CompileParser;
|
||||
public Tuple<Tuple<int, int>, Tuple<int, int>>[] JumpPointerCache;
|
||||
}
|
||||
|
||||
public List<IRSentenceMatcher> 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<int> RuntimePointerStack = 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;
|
||||
internal readonly Stack<HashSet<string>> 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(),
|
||||
};
|
||||
}
|
||||
}
|
||||
|
@@ -17,6 +17,7 @@ namespace Convention.RScript
|
||||
Dictionary<string, RScriptVariableEntry> 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<string, RScriptVariableEntry> Run(SerializableClass data, RScriptImportClass import = null, RScriptVariables variables = null);
|
||||
IEnumerator RunAsync(SerializableClass data, RScriptImportClass import = null, RScriptVariables variables = null);
|
||||
}
|
||||
@@ -56,16 +57,8 @@ namespace Convention.RScript
|
||||
// Skip single-line comment
|
||||
if (line[i + 1] == '/')
|
||||
{
|
||||
while (i < line.Length && line[i] != '\n')
|
||||
i++;
|
||||
}
|
||||
// Skip multi-line comment
|
||||
else if (line[i + 1] == '*')
|
||||
{
|
||||
i += 2;
|
||||
while (i + 1 < line.Length && !(line[i] == '*' && line[i + 1] == '/'))
|
||||
i++;
|
||||
i++;
|
||||
PushBuilder();
|
||||
break;
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -74,9 +67,8 @@ namespace Convention.RScript
|
||||
}
|
||||
else if (c == '#')
|
||||
{
|
||||
// Skip single-line comment
|
||||
while (i < line.Length && line[i] != '\n')
|
||||
i++;
|
||||
PushBuilder();
|
||||
break;
|
||||
}
|
||||
else if (c == '\"')
|
||||
{
|
||||
@@ -126,10 +118,7 @@ namespace Convention.RScript
|
||||
}
|
||||
}
|
||||
}
|
||||
if (builder.Length > 0)
|
||||
{
|
||||
PushBuilder();
|
||||
}
|
||||
PushBuilder();
|
||||
|
||||
return statements.Where(s => !string.IsNullOrWhiteSpace(s));
|
||||
}
|
||||
@@ -163,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<string, RScriptVariableEntry> Run(SerializableClass data, RScriptImportClass import = null, RScriptVariables variables = null)
|
||||
{
|
||||
|
@@ -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<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;
|
||||
}
|
||||
|
Reference in New Issue
Block a user