Compare commits
2 Commits
b8a87bae4c
...
70051b46a5
Author | SHA1 | Date | |
---|---|---|---|
70051b46a5 | |||
35800776b9 |
@@ -57,6 +57,11 @@ namespace Convention.RScript
|
||||
public string content;
|
||||
public List<string> info;
|
||||
public Mode mode;
|
||||
|
||||
public override string ToString()
|
||||
{
|
||||
return $"{mode.ToString()}/: {content}";
|
||||
}
|
||||
}
|
||||
|
||||
public interface IRSentenceMatcher
|
||||
@@ -69,9 +74,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 +101,47 @@ 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;
|
||||
namespaceName = "";
|
||||
}
|
||||
else
|
||||
{
|
||||
throw new RScriptRuntimeException($"Namespace is invalid", i);
|
||||
}
|
||||
}
|
||||
}
|
||||
if (namespaceLayers.Count > 0)
|
||||
@@ -128,10 +155,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 +280,24 @@ namespace Convention.RScript
|
||||
GotoPointerStack.Push(CurrentRuntimePointer);
|
||||
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
|
||||
{
|
||||
throw new RScriptRuntimeException($"Label '{sentence.content}' not found.", CurrentRuntimePointer);
|
||||
@@ -279,7 +321,7 @@ namespace Convention.RScript
|
||||
}
|
||||
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)
|
||||
{
|
||||
throw new NotImplementedException($"No position to back.");
|
||||
throw new RScriptRuntimeException($"No position to back.", CurrentRuntimePointer);
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -300,6 +342,11 @@ namespace Convention.RScript
|
||||
}
|
||||
}
|
||||
|
||||
private void DoEnterNamedSpace(RScriptSentence sentence)
|
||||
{
|
||||
CurrentRuntimePointer = NamespaceLayer[NamespaceLabels[sentence.content]];
|
||||
}
|
||||
|
||||
private object RunNextStep(ExpressionParser parser)
|
||||
{
|
||||
var sentence = CurrentSentence;
|
||||
@@ -337,6 +384,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