From 35800776b97fe64a848c8319502b19fdcaed704f Mon Sep 17 00:00:00 2001 From: ninemine <1371605831@qq.com> Date: Wed, 15 Oct 2025 21:18:14 +0800 Subject: [PATCH] =?UTF-8?q?=E6=9E=84=E5=BB=BA=E5=91=BD=E5=90=8D=E7=A9=BA?= =?UTF-8?q?=E9=97=B4=E8=A7=84=E5=88=99?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- RScriptContext.cs | 87 +++++++++++++++++++++++++++++++++++------------ 1 file changed, 66 insertions(+), 21 deletions(-) diff --git a/RScriptContext.cs b/RScriptContext.cs index 00ec14b..f7322b4 100644 --- a/RScriptContext.cs +++ b/RScriptContext.cs @@ -69,9 +69,9 @@ namespace Convention.RScript public readonly RScriptImportClass Import; public readonly RScriptVariables Variables; private readonly RScriptSentence[] Sentences; - private readonly Dictionary Labels; - private readonly Dictionary NamespaceLayer; - private readonly Dictionary NamespaceLabels; + private readonly Dictionary Labels = new(); + private readonly Dictionary NamespaceLayer = new(); + private readonly Dictionary NamespaceLabels = new(); public List SentenceParser = new() { @@ -96,25 +96,46 @@ namespace Convention.RScript return result; } - private void BuildUpLabelsAndNamespace(ref Dictionary labelIndicator, ref Dictionary namespaceIndicator) + private void BuildUpLabelsAndNamespace() { Stack namespaceLayers = new(); + string namespaceName = ""; for (int i = 0, e = Sentences.Length; i != e; i++) { - if (Sentences[i].mode == RScriptSentence.Mode.Label) + var sentence = Sentences[i]; + if (string.IsNullOrEmpty(namespaceName)) { - labelIndicator[Sentences[i].content] = i; + if (sentence.mode == RScriptSentence.Mode.Label) + { + this.Labels[Sentences[i].content] = i; + } + else if (sentence.mode == RScriptSentence.Mode.EnterNamespace) + { + namespaceLayers.Push(i); + } + else if (sentence.mode == RScriptSentence.Mode.ExitNamespace) + { + if (namespaceLayers.Count == 0) + throw new RScriptRuntimeException("Namespace exit without enter.", i); + var enterPointer = namespaceLayers.Pop(); + this.NamespaceLayer[enterPointer] = i; + } + else if (sentence.mode == RScriptSentence.Mode.NamedSpace) + { + namespaceName = sentence.content; + } } - else if (Sentences[i].mode == RScriptSentence.Mode.EnterNamespace) + else { - namespaceLayers.Push(i); - } - else if (Sentences[i].mode == RScriptSentence.Mode.ExitNamespace) - { - if (namespaceLayers.Count == 0) - throw new RScriptRuntimeException("Namespace exit without enter.", i); - var enterPointer = namespaceLayers.Pop(); - namespaceIndicator[enterPointer] = i; + if (sentence.mode == RScriptSentence.Mode.EnterNamespace) + { + namespaceLayers.Push(i); + this.NamespaceLabels[namespaceName] = i; + } + else + { + throw new RScriptRuntimeException($"Namespace is invalid", i); + } } } if (namespaceLayers.Count > 0) @@ -128,10 +149,7 @@ namespace Convention.RScript this.Import = import ?? new(); this.Variables = variables ?? new(); this.Sentences = (from item in expressions select ParseToSentence(item)).ToArray(); - this.Labels = new(); - this.NamespaceLayer = new(); - this.NamespaceLabels = new(); - BuildUpLabelsAndNamespace(ref this.Labels, ref this.NamespaceLayer); + BuildUpLabelsAndNamespace(); } @@ -256,6 +274,23 @@ namespace Convention.RScript GotoPointerStack.Push(CurrentRuntimePointer); DoJumpRuntimePointer(parser, labelPointer); } + else if (NamespaceLabels.TryGetValue(sentence.content, out labelPointer)) + { + int current = CurrentRuntimePointer; + DoEnterNamespace(parser); + for (int e = NamespaceLayer[NamespaceLabels[sentence.content]]; ;) + { + RunNextStep(parser); + if (CurrentRuntimePointer >= Sentences.Length) + break ; + else if (CurrentRuntimePointer != e) + break; + else + CurrentRuntimePointer++; + } + DoExitNamespace(parser); + CurrentRuntimePointer = current; + } else { throw new RScriptRuntimeException($"Label '{sentence.content}' not found.", CurrentRuntimePointer); @@ -279,7 +314,7 @@ namespace Convention.RScript } else { - throw new NotImplementedException($"No namespace to break."); + throw new RScriptRuntimeException($"No namespace to break.", CurrentRuntimePointer); } } } @@ -291,7 +326,7 @@ namespace Convention.RScript { if (GotoPointerStack.Count == 0) { - throw new NotImplementedException($"No position to back."); + throw new RScriptRuntimeException($"No position to back.", CurrentRuntimePointer); } else { @@ -300,6 +335,11 @@ namespace Convention.RScript } } + private void DoEnterNamedSpace(RScriptSentence sentence) + { + CurrentRuntimePointer = NamespaceLayer[NamespaceLabels[sentence.content]]; + } + private object RunNextStep(ExpressionParser parser) { var sentence = CurrentSentence; @@ -337,6 +377,11 @@ namespace Convention.RScript DoBackpoint(parser, sentence); } break; + case RScriptSentence.Mode.NamedSpace: + { + DoEnterNamedSpace(sentence); + } + break; default: // Do nothing break;