Skip to content

Commit 114350b

Browse files
big changes
1 parent ec55a51 commit 114350b

32 files changed

+599
-200
lines changed
Lines changed: 28 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
1-
using SER.Code.ContextSystem.Structures;
1+
using SER.Code.ContextSystem.Extensions;
2+
using SER.Code.ContextSystem.Structures;
23

34
namespace SER.Code.ContextSystem.BaseContexts;
45

@@ -10,23 +11,42 @@ public abstract class LoopContext : StatementContext, IExtendableStatement, IKey
1011
public abstract string KeywordName { get; }
1112
public abstract string Description { get; }
1213
public abstract string[] Arguments { get; }
13-
14-
public bool SkipThisIteration { get; protected set; }
15-
public bool ExitLoop { get; protected set; }
14+
15+
private bool ReceivedContinue { get; set; }
16+
protected bool ReceivedBreak { get; set; }
1617

1718
protected override void OnReceivedControlMessageFromChild(ParentContextControlMessage msg)
1819
{
1920
switch (msg)
2021
{
21-
case ParentContextControlMessage.LoopContinue:
22-
SkipThisIteration = true;
22+
case ParentContextControlMessage.Continue:
23+
ReceivedContinue = true;
2324
return;
24-
case ParentContextControlMessage.LoopBreak:
25-
ExitLoop = true;
25+
case ParentContextControlMessage.Break:
26+
ReceivedBreak = true;
2627
return;
2728
default:
2829
ParentContext?.SendControlMessage(msg);
2930
break;
3031
}
3132
}
33+
34+
protected override IEnumerator<float> RunChildren()
35+
{
36+
foreach (var coro in Children
37+
.TakeWhile(_ => !ReceivedBreak)
38+
.TakeWhile(_ => Script.IsRunning)
39+
.Select(child => child.ExecuteBaseContext()))
40+
{
41+
while (coro.MoveNext())
42+
{
43+
yield return coro.Current;
44+
}
45+
46+
if (!ReceivedContinue) continue;
47+
48+
ReceivedContinue = false;
49+
break;
50+
}
51+
}
3252
}
Lines changed: 45 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,45 @@
1+
using SER.Code.ContextSystem.CommunicationInterfaces;
2+
using SER.Code.Helpers.Extensions;
3+
using SER.Code.Helpers.ResultSystem;
4+
using SER.Code.TokenSystem.Tokens.VariableTokens;
5+
using SER.Code.ValueSystem;
6+
using SER.Code.VariableSystem.Bases;
7+
8+
namespace SER.Code.ContextSystem.BaseContexts;
9+
10+
public abstract class LoopSingleIterationVariableContext<TVal> : LoopContext, IAcceptOptionalVariableDefinitions
11+
where TVal : Value
12+
{
13+
private VariableToken? _iterationVariableToken;
14+
private Variable? _iterationVariable;
15+
16+
public Result SetOptionalVariables(params VariableToken[] variableTokens)
17+
{
18+
if (variableTokens.FirstOrDefault() is not {} varToken) return true;
19+
20+
if (!varToken.ValueType.IsAssignableFrom(typeof(TVal)))
21+
{
22+
return $"Provided variable '{varToken.RawRepr}' cannot be used for this loop, " +
23+
$"as it cannot hold a {typeof(TVal).FriendlyTypeName()}";
24+
}
25+
26+
_iterationVariableToken = varToken;
27+
return true;
28+
}
29+
30+
protected void SetVariable(TVal value)
31+
{
32+
if (_iterationVariableToken is null) return;
33+
34+
_iterationVariable = Variable.Create(_iterationVariableToken.Name, value);
35+
Script.AddVariable(_iterationVariable);
36+
}
37+
38+
protected void RemoveVariable()
39+
{
40+
if (_iterationVariable is null) return;
41+
42+
Script.RemoveVariable(_iterationVariable);
43+
_iterationVariable = null;
44+
}
45+
}

Code/ContextSystem/BaseContexts/StatementContext.cs

Lines changed: 15 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
1-
using SER.Code.ContextSystem.Structures;
1+
using SER.Code.ContextSystem.Extensions;
2+
using SER.Code.ContextSystem.Structures;
23
using SER.Code.Helpers;
34

45
namespace SER.Code.ContextSystem.BaseContexts;
@@ -17,4 +18,17 @@ protected virtual void OnReceivedControlMessageFromChild(ParentContextControlMes
1718
{
1819
ParentContext?.SendControlMessage(msg);
1920
}
21+
22+
protected virtual IEnumerator<float> RunChildren()
23+
{
24+
foreach (var coro in Children
25+
.TakeWhile(_ => Script.IsRunning)
26+
.Select(child => child.ExecuteBaseContext()))
27+
{
28+
while (coro.MoveNext())
29+
{
30+
yield return coro.Current;
31+
}
32+
}
33+
}
2034
}

Code/ContextSystem/BaseContexts/YieldingContext.cs

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,17 @@
1-
using SER.Code.Helpers;
1+
using SER.Code.ContextSystem.Structures;
2+
using SER.Code.Helpers;
23

34
namespace SER.Code.ContextSystem.BaseContexts;
45

56
public abstract class YieldingContext : Context
67
{
78
public IEnumerator<float> Run()
89
{
10+
if (this is INotRunningContext)
11+
{
12+
yield break;
13+
}
14+
915
var prof = Script.Profile is not null
1016
? new Profile(Script.Profile, $"running YieldingContext {Name}")
1117
: null;
Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
using SER.Code.Helpers.ResultSystem;
2+
using SER.Code.TokenSystem.Tokens.VariableTokens;
3+
4+
namespace SER.Code.ContextSystem.CommunicationInterfaces;
5+
6+
/// <summary>
7+
/// Marks that the context before is a statement that accepts optional variable definitions.
8+
/// </summary>
9+
public interface IAcceptOptionalVariableDefinitions
10+
{
11+
public Result SetOptionalVariables(params VariableToken[] variableTokens);
12+
}
Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
using SER.Code.ContextSystem.BaseContexts;
2+
using SER.Code.Helpers.ResultSystem;
3+
4+
namespace SER.Code.ContextSystem.CommunicationInterfaces;
5+
6+
/// <summary>
7+
/// Requests the previous statement context to be provided
8+
/// </summary>
9+
public interface IRequireCurrentStatement
10+
{
11+
public Result AcceptStatement(StatementContext context);
12+
}

Code/ContextSystem/Contexter.cs

Lines changed: 34 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,9 @@
11
using SER.Code.ContextSystem.BaseContexts;
2+
using SER.Code.ContextSystem.CommunicationInterfaces;
23
using SER.Code.ContextSystem.Contexts.Control;
34
using SER.Code.ContextSystem.Structures;
45
using SER.Code.Helpers;
6+
using SER.Code.Helpers.Extensions;
57
using SER.Code.Helpers.ResultSystem;
68
using SER.Code.ScriptSystem;
79
using SER.Code.TokenSystem.Structures;
@@ -16,7 +18,7 @@ public static class Contexter
1618
{
1719
public static TryGet<Context[]> ContextLines(Line[] lines, Script scr)
1820
{
19-
List<StatementContext> statementStack = [];
21+
Stack<StatementContext> statementStack = [];
2022
List<Context> contexts = [];
2123

2224
foreach (var line in lines)
@@ -34,6 +36,7 @@ public static TryGet<Context[]> ContextLines(Line[] lines, Script scr)
3436
{
3537
return mainErr + addError;
3638
}
39+
Log.Debug($"current statement stack: {statementStack.Select(s => s.GetType().Name).JoinStrings(" -> ")}");
3740
}
3841

3942
return contexts.ToArray();
@@ -42,21 +45,40 @@ public static TryGet<Context[]> ContextLines(Line[] lines, Script scr)
4245
private static Result TryAddResult(
4346
Context context,
4447
uint lineNum,
45-
List<StatementContext> statementStack,
48+
Stack<StatementContext> statementStack,
4649
List<Context> contexts
4750
) {
4851
Result rs = $"Invalid context {context} in line {lineNum}.";
4952

50-
if (context is EndStatementContext)
53+
Log.Debug($"Trying to add context {context} in line {lineNum}");
54+
55+
switch (context)
5156
{
52-
if (statementStack.Count == 0)
53-
return rs + "There is no statement to close with the 'end' keyword!";
57+
case EndStatementContext:
58+
{
59+
if (statementStack.Count == 0)
60+
return rs + "There is no statement to close with the 'end' keyword!";
5461

55-
statementStack.RemoveAt(statementStack.Count - 1);
56-
return true;
62+
statementStack.Pop();
63+
return true;
64+
}
65+
case IRequireCurrentStatement rqsContext:
66+
{
67+
if (statementStack.Count == 0)
68+
{
69+
return rs + $"{context.Name} expected to be inside a statement, but it isn't.";
70+
}
71+
72+
if (rqsContext.AcceptStatement(statementStack.Peek()).HasErrored(out var asError))
73+
{
74+
return rs + asError;
75+
}
76+
77+
break;
78+
}
5779
}
5880

59-
var currentStatement = statementStack.LastOrDefault();
81+
var currentStatement = statementStack.FirstOrDefault();
6082
if (context is StatementContext treeExtenderContext and IStatementExtender treeExtenderInfo)
6183
{
6284
if (currentStatement is null)
@@ -75,8 +97,8 @@ List<Context> contexts
7597
}
7698

7799
extendable.RegisteredSignals[treeExtenderInfo.Extends] = treeExtenderContext.Run;
78-
statementStack.RemoveAt(statementStack.Count - 1);
79-
statementStack.Add(treeExtenderContext);
100+
statementStack.Pop();
101+
statementStack.Push(treeExtenderContext);
80102
return true;
81103
}
82104

@@ -96,7 +118,7 @@ List<Context> contexts
96118
}
97119

98120
if (context is StatementContext treeContext)
99-
statementStack.Add(treeContext);
121+
statementStack.Push(treeContext);
100122

101123
Log.Debug($"Line {lineNum} has been contexted to {context}");
102124
return true;
@@ -130,7 +152,7 @@ List<Context> contexts
130152

131153
private static Result HandleCurrentContext(BaseToken token, Context context, out bool endLineContexting)
132154
{
133-
Result rs = $"Cannot add token {token} to context {context}";
155+
Result rs = $"Cannot add '{token.RawRep}' to {context}";
134156
Log.Debug($"Handling token {token} in context {context}");
135157

136158
var result = context.TryAddToken(token);

Code/ContextSystem/Contexts/Control/IfStatementContext.cs

Lines changed: 6 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -62,37 +62,19 @@ protected override IEnumerator<float> Execute()
6262
yield break;
6363
}
6464

65-
var coro = enumerator();
66-
while (coro.MoveNext())
65+
var didntExecuteCoro = enumerator();
66+
while (didntExecuteCoro.MoveNext())
6767
{
68-
if (!Script.IsRunning)
69-
{
70-
yield break;
71-
}
72-
73-
yield return coro.Current;
68+
yield return didntExecuteCoro.Current;
7469
}
7570

7671
yield break;
7772
}
7873

79-
foreach (var child in Children)
74+
var coro = RunChildren();
75+
while (coro.MoveNext())
8076
{
81-
if (!Script.IsRunning)
82-
{
83-
yield break;
84-
}
85-
86-
var coro = child.ExecuteBaseContext();
87-
while (coro.MoveNext())
88-
{
89-
if (!Script.IsRunning)
90-
{
91-
yield break;
92-
}
93-
94-
yield return coro.Current;
95-
}
77+
yield return coro.Current;
9678
}
9779
}
9880
}

0 commit comments

Comments
 (0)