using Convention.RScript.Parser; using System.Diagnostics.CodeAnalysis; namespace Convention.RScript.Runner { public class GoToRunner : JumpRuntimePointerRunner { [return: MaybeNull] public override object Run(ExpressionParser parser, RScriptSentence sentence, RScriptContext context) { // 检查并跳转到指定标签 if (parser.Evaluate(sentence.info[0])) { if (context.Labels.TryGetValue(sentence.content, out var labelPointer)) { context.GotoPointerStack.Push(context.CurrentRuntimePointer); DoJumpRuntimePointer(parser, labelPointer, context); } else if (context.NamespaceLabels.TryGetValue(sentence.content, out labelPointer)) { int current = context.CurrentRuntimePointer; //DoEnterNamespace(parser); context.SentenceRunners[RScriptSentence.Mode.EnterNamespace].Run(parser, context.CurrentSentence, context); context.CurrentRuntimePointer = labelPointer; for (int e = context.NamespaceLayer[context.NamespaceLabels[sentence.content]]; ;) { context.RunNextStep(parser); if (context.CurrentRuntimePointer >= context.Sentences.Length) break; else if (context.CurrentRuntimePointer == e) break; else context.CurrentRuntimePointer++; } //context.DoExitNamespace(parser); context.SentenceRunners[RScriptSentence.Mode.ExitNamespace].Run(parser, context.CurrentSentence, context); context.CurrentRuntimePointer = current; } else { throw new RScriptRuntimeException($"Label '{sentence.content}' not found.", context.CurrentRuntimePointer); } } return null; } } }