using Convention.RScript.Parser; using System; using System.Diagnostics.CodeAnalysis; namespace Convention.RScript.Runner { public abstract class JumpRuntimePointerRunner : IRSentenceRunner { protected static void DoJumpRuntimePointer(ExpressionParser parser, int target, RScriptContext context) { 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.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; } // 对上层的最深影响 for (; depth < 0; depth++) { try { context.SentenceRunners[RScriptSentence.Mode.ExitNamespace].Run(parser, context.CurrentSentence, context); } catch (Exception ex) { throw new RScriptRuntimeException($"Jump pointer with error", currentPointer, ex); } } // 恢复正确的层数 for (int i = depth, e = lastLayer; i < e; i++) { try { context.SentenceRunners[RScriptSentence.Mode.EnterNamespace].Run(parser, context.CurrentSentence, context); } catch (Exception ex) { throw new RScriptRuntimeException($"Jump pointer with error", currentPointer, ex); } } } public abstract void Compile(ExpressionParser parser, RScriptSentence sentence, RScriptContext context); [return: MaybeNull] public abstract object Run(ExpressionParser parser, RScriptSentence sentence, RScriptContext context); } }