构建命名空间规则
This commit is contained in:
@@ -69,9 +69,9 @@ namespace Convention.RScript
|
||||
public readonly RScriptImportClass Import;
|
||||
public readonly RScriptVariables Variables;
|
||||
private readonly RScriptSentence[] Sentences;
|
||||
private readonly Dictionary<string, int> Labels;
|
||||
private readonly Dictionary<int, int> NamespaceLayer;
|
||||
private readonly Dictionary<string, int> NamespaceLabels;
|
||||
private readonly Dictionary<string, int> Labels = new();
|
||||
private readonly Dictionary<int, int> NamespaceLayer = new();
|
||||
private readonly Dictionary<string, int> NamespaceLabels = new();
|
||||
|
||||
public List<IRSentenceMatcher> SentenceParser = new()
|
||||
{
|
||||
@@ -96,25 +96,46 @@ namespace Convention.RScript
|
||||
return result;
|
||||
}
|
||||
|
||||
private void BuildUpLabelsAndNamespace(ref Dictionary<string, int> labelIndicator, ref Dictionary<int, int> namespaceIndicator)
|
||||
private void BuildUpLabelsAndNamespace()
|
||||
{
|
||||
Stack<int> 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;
|
||||
|
Reference in New Issue
Block a user