Compare commits
2 Commits
b8a87bae4c
...
70051b46a5
Author | SHA1 | Date | |
---|---|---|---|
70051b46a5 | |||
35800776b9 |
@@ -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;
|
||||||
|
Reference in New Issue
Block a user