Compare commits

...

2 Commits

Author SHA1 Message Date
70051b46a5 namespace已经可以使用 2025-10-15 23:47:51 +08:00
35800776b9 构建命名空间规则 2025-10-15 21:18:14 +08:00

View File

@@ -57,6 +57,11 @@ namespace Convention.RScript
public string content; public string content;
public List<string> info; public List<string> info;
public Mode mode; public Mode mode;
public override string ToString()
{
return $"{mode.ToString()}/: {content}";
}
} }
public interface IRSentenceMatcher public interface IRSentenceMatcher
@@ -69,9 +74,9 @@ namespace Convention.RScript
public readonly RScriptImportClass Import; public readonly RScriptImportClass Import;
public readonly RScriptVariables Variables; public readonly RScriptVariables Variables;
private readonly RScriptSentence[] Sentences; private readonly RScriptSentence[] Sentences;
private readonly Dictionary<string, int> Labels; private readonly Dictionary<string, int> Labels = new();
private readonly Dictionary<int, int> NamespaceLayer; private readonly Dictionary<int, int> NamespaceLayer = new();
private readonly Dictionary<string, int> NamespaceLabels; private readonly Dictionary<string, int> NamespaceLabels = new();
public List<IRSentenceMatcher> SentenceParser = new() public List<IRSentenceMatcher> SentenceParser = new()
{ {
@@ -96,25 +101,47 @@ namespace Convention.RScript
return result; return result;
} }
private void BuildUpLabelsAndNamespace(ref Dictionary<string, int> labelIndicator, ref Dictionary<int, int> namespaceIndicator) private void BuildUpLabelsAndNamespace()
{ {
Stack<int> namespaceLayers = new(); Stack<int> namespaceLayers = new();
string namespaceName = "";
for (int i = 0, e = Sentences.Length; i != e; i++) 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); if (sentence.mode == RScriptSentence.Mode.EnterNamespace)
} {
else if (Sentences[i].mode == RScriptSentence.Mode.ExitNamespace) namespaceLayers.Push(i);
{ this.NamespaceLabels[namespaceName] = i;
if (namespaceLayers.Count == 0) namespaceName = "";
throw new RScriptRuntimeException("Namespace exit without enter.", i); }
var enterPointer = namespaceLayers.Pop(); else
namespaceIndicator[enterPointer] = i; {
throw new RScriptRuntimeException($"Namespace is invalid", i);
}
} }
} }
if (namespaceLayers.Count > 0) if (namespaceLayers.Count > 0)
@@ -128,10 +155,7 @@ namespace Convention.RScript
this.Import = import ?? new(); this.Import = import ?? new();
this.Variables = variables ?? new(); this.Variables = variables ?? new();
this.Sentences = (from item in expressions select ParseToSentence(item)).ToArray(); this.Sentences = (from item in expressions select ParseToSentence(item)).ToArray();
this.Labels = new(); BuildUpLabelsAndNamespace();
this.NamespaceLayer = new();
this.NamespaceLabels = new();
BuildUpLabelsAndNamespace(ref this.Labels, ref this.NamespaceLayer);
} }
@@ -256,6 +280,24 @@ namespace Convention.RScript
GotoPointerStack.Push(CurrentRuntimePointer); GotoPointerStack.Push(CurrentRuntimePointer);
DoJumpRuntimePointer(parser, labelPointer); DoJumpRuntimePointer(parser, labelPointer);
} }
else if (NamespaceLabels.TryGetValue(sentence.content, out labelPointer))
{
int current = CurrentRuntimePointer;
DoEnterNamespace(parser);
CurrentRuntimePointer = labelPointer;
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 else
{ {
throw new RScriptRuntimeException($"Label '{sentence.content}' not found.", CurrentRuntimePointer); throw new RScriptRuntimeException($"Label '{sentence.content}' not found.", CurrentRuntimePointer);
@@ -279,7 +321,7 @@ namespace Convention.RScript
} }
else else
{ {
throw new NotImplementedException($"No namespace to break."); throw new RScriptRuntimeException($"No namespace to break.", CurrentRuntimePointer);
} }
} }
} }
@@ -291,7 +333,7 @@ namespace Convention.RScript
{ {
if (GotoPointerStack.Count == 0) if (GotoPointerStack.Count == 0)
{ {
throw new NotImplementedException($"No position to back."); throw new RScriptRuntimeException($"No position to back.", CurrentRuntimePointer);
} }
else else
{ {
@@ -300,6 +342,11 @@ namespace Convention.RScript
} }
} }
private void DoEnterNamedSpace(RScriptSentence sentence)
{
CurrentRuntimePointer = NamespaceLayer[NamespaceLabels[sentence.content]];
}
private object RunNextStep(ExpressionParser parser) private object RunNextStep(ExpressionParser parser)
{ {
var sentence = CurrentSentence; var sentence = CurrentSentence;
@@ -337,6 +384,11 @@ namespace Convention.RScript
DoBackpoint(parser, sentence); DoBackpoint(parser, sentence);
} }
break; break;
case RScriptSentence.Mode.NamedSpace:
{
DoEnterNamedSpace(sentence);
}
break;
default: default:
// Do nothing // Do nothing
break; break;