Skip to content

Commit e574af6

Browse files
update implementations of value properties
1 parent df642aa commit e574af6

29 files changed

Lines changed: 394 additions & 183 deletions

Code/ContextSystem/Contexts/Control/Loops/OverLoop.cs

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -41,11 +41,11 @@ over @all
4141
over @all
4242
with @plr
4343
44-
Print "found player {@plr name}"
44+
Print "found player {@plr -> name}"
4545
end
4646
4747
# this also works for collections:
48-
&inventory = {@sender inventory}
48+
&inventory = @sender -> inventory
4949
over &inventory
5050
with *item
5151
@@ -61,7 +61,7 @@ with @plr
6161
over @all
6262
with @plr $index
6363
64-
Print "found player #{$index}: {@plr name}"
64+
Print "found player #{$index}: {@plr -> name}"
6565
end
6666
""";
6767

Code/ContextSystem/Contexts/ValueExpressionContext.cs

Lines changed: 84 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -45,6 +45,10 @@ public ValueExpressionContext(BaseToken initial, bool allowsYielding)
4545
{
4646
_handler = new MethodHandler(methodToken, allowsYielding, initial.Script);
4747
}
48+
else if (initial is KeywordToken { RawRep: "run"} )
49+
{
50+
_handler = new FunctionCallHandler(initial.Script);
51+
}
4852
else if (initial is not IValueToken valToken)
4953
{
5054
_error = $"{initial} is not a valid way to get a value.";
@@ -103,7 +107,8 @@ public override Result VerifyCurrentState()
103107
/// </summary>
104108
public IEnumerator<float> Run()
105109
{
106-
var coro = _handler!.Run();
110+
if (_handler is null) yield break;
111+
var coro = _handler.Run();
107112
while (coro.MoveNext()) yield return coro.Current;
108113
}
109114

@@ -192,10 +197,15 @@ public override TryGet<Value> GetReturnValue()
192197
var prop = _propertyNames.Dequeue();
193198
if (!current.Properties.TryGetValue(prop, out var propInfo))
194199
{
195-
return $"{value} does not have property '{prop}'.";
200+
return $"{current} does not have property '{prop}'.";
201+
}
202+
203+
if (propInfo.GetValue(current).HasErrored(out var fetchError, out var fetchedValue))
204+
{
205+
return fetchError;
196206
}
197207

198-
current = propInfo.Func(current);
208+
current = fetchedValue;
199209
}
200210

201211
return current;
@@ -205,6 +215,7 @@ public override TryAddTokenRes TryAddToken(BaseToken token)
205215
{
206216
if (token is SymbolToken { IsArrow: true })
207217
{
218+
_exprRepr += $" {token.RawRep}";
208219
return TryAddTokenRes.Continue();
209220
}
210221

@@ -217,13 +228,14 @@ public override TryAddTokenRes TryAddToken(BaseToken token)
217228
{
218229
_exprRepr += $" {token.RawRep}";
219230
_lastValueType = property.ReturnType;
220-
break;
231+
goto found;
221232
}
222233
}
223234

224235
return TryAddTokenRes.Error($"'{token.RawRep}' is not a valid property of '{_exprRepr}' value.");
225236
}
226237

238+
found:
227239
_propertyNames.Enqueue(token.RawRep);
228240
return TryAddTokenRes.Continue();
229241
}
@@ -278,4 +290,72 @@ public override IEnumerator<float> Run()
278290
{
279291
yield break;
280292
}
293+
}
294+
295+
public class FunctionCallHandler(Script scr) : ValueExpressionContext.Handler
296+
{
297+
private FuncStatement? _func;
298+
private readonly List<IValueToken> _providedValues = [];
299+
300+
public override TryGet<Value> GetReturnValue()
301+
{
302+
if (_func!.ReturnedValue is { } value) return value;
303+
return _func.MissingValueHint;
304+
}
305+
306+
public override TryAddTokenRes TryAddToken(BaseToken token)
307+
{
308+
if (_func is null)
309+
{
310+
if (scr.DefinedFunctions.TryGetValue(token.RawRep, out var func))
311+
{
312+
_func = func;
313+
}
314+
else
315+
{
316+
return TryAddTokenRes.Error($"Function '{token.RawRep}' is not defined.");
317+
}
318+
}
319+
320+
if (token is IValueToken valToken)
321+
{
322+
_providedValues.Add(valToken);
323+
return TryAddTokenRes.Continue();
324+
}
325+
326+
return TryAddTokenRes.Error($"Unexpected token '{token.RawRep}'");
327+
}
328+
329+
public override Result VerifyCurrentState()
330+
{
331+
return Result.Assert(
332+
_func is not null,
333+
"Function to run was not provided."
334+
);
335+
}
336+
337+
public override IEnumerator<float> Run()
338+
{
339+
List<Value> varsToProvide = [];
340+
foreach (var valToken in _providedValues)
341+
{
342+
if (valToken.Value().HasErrored(out var error, out var variable))
343+
{
344+
throw new ScriptRuntimeError(_func!,
345+
$"Cannot run {_func!.FriendlyName}: {error}"
346+
);
347+
}
348+
349+
varsToProvide.Add(variable);
350+
}
351+
352+
var coro = _func!.RunProperly(varsToProvide.ToArray());
353+
while (coro.MoveNext()) yield return coro.Current;
354+
}
355+
356+
public override string FriendlyName => _func!.FriendlyName;
357+
358+
public override TypeOfValue PossibleValues =>
359+
_func?.Returns
360+
?? throw new AndrzejFuckedUpException("Function has no return type.");
281361
}
Lines changed: 3 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -1,25 +1,10 @@
1-
using SER.Code.TokenSystem.Tokens.ValueTokens;
2-
using SER.Code.TokenSystem.Tokens.VariableTokens;
1+
using SER.Code.TokenSystem.Tokens.VariableTokens;
32
using SER.Code.ValueSystem;
43
using SER.Code.VariableSystem.Variables;
54

65
namespace SER.Code.ContextSystem.Contexts.VariableDefinition;
76

8-
public class LiteralVariableDefinitionContext :
9-
VariableDefinitionContext<VariableToken<LiteralVariable, LiteralValue>, LiteralValue, LiteralVariable>
10-
{
11-
public LiteralVariableDefinitionContext(VariableToken<LiteralVariable, LiteralValue> varToken) : base(varToken)
12-
{
13-
AdditionalTokenParser = token =>
14-
{
15-
if (token is TextToken textToken)
16-
{
17-
return () => textToken.Value;
18-
}
19-
20-
return null;
21-
};
22-
}
23-
}
7+
public class LiteralVariableDefinitionContext(VariableToken<LiteralVariable, LiteralValue> varToken) :
8+
VariableDefinitionContext<VariableToken<LiteralVariable, LiteralValue>, LiteralValue, LiteralVariable>(varToken);
249

2510

Code/ContextSystem/Contexts/VariableDefinition/PlayerVariableDefinitionContext.cs

Lines changed: 1 addition & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -8,21 +8,4 @@
88
namespace SER.Code.ContextSystem.Contexts.VariableDefinition;
99

1010
public class PlayerVariableDefinitionContext(VariableToken<PlayerVariable, PlayerValue> varToken) :
11-
VariableDefinitionContext<VariableToken<PlayerVariable, PlayerValue>, PlayerValue, PlayerVariable>(varToken)
12-
{
13-
protected override (TryAddTokenRes result, Func<PlayerValue> parser) AdditionalParsing(BaseToken token)
14-
{
15-
if (token is ParenthesesToken { RawContent: "" })
16-
{
17-
Log.ScriptWarn(
18-
token.Script,
19-
$"Using () to create an empty player variable will be removed in future versions of SER. " +
20-
$"Please use the @empty variable to create an empty variable instead."
21-
);
22-
23-
return (TryAddTokenRes.End(), () => new([]));
24-
}
25-
26-
return base.AdditionalParsing(token);
27-
}
28-
}
11+
VariableDefinitionContext<VariableToken<PlayerVariable, PlayerValue>, PlayerValue, PlayerVariable>(varToken);

Code/ContextSystem/Contexts/VariableDefinition/VariableDefinitionContext.cs

Lines changed: 22 additions & 87 deletions
Original file line numberDiff line numberDiff line change
@@ -1,16 +1,13 @@
11
using SER.Code.ContextSystem.BaseContexts;
2-
using SER.Code.ContextSystem.Extensions;
3-
using SER.Code.ContextSystem.Interfaces;
2+
using SER.Code.ContextSystem.Contexts;
43
using SER.Code.ContextSystem.Structures;
54
using SER.Code.Exceptions;
65
using SER.Code.Extensions;
76
using SER.Code.Helpers.ResultSystem;
8-
using SER.Code.TokenSystem.Structures;
97
using SER.Code.TokenSystem.Tokens;
108
using SER.Code.TokenSystem.Tokens.VariableTokens;
119
using SER.Code.ValueSystem;
1210
using SER.Code.VariableSystem.Bases;
13-
using Log = SER.Code.Helpers.Log;
1411

1512
namespace SER.Code.ContextSystem.Contexts.VariableDefinition;
1613

@@ -25,16 +22,8 @@ public abstract class VariableDefinitionContext<TVarToken, TValue, TVariable>(TV
2522
where TValue : Value
2623
where TVariable : Variable<TValue>
2724
{
28-
protected virtual (TryAddTokenRes result, Func<TValue> parser) AdditionalParsing(BaseToken token)
29-
{
30-
return (TryAddTokenRes.Error($"Value '{token.RawRep}' ({token.GetType().AccurateName}) cannot be assigned to {typeof(TVarToken).AccurateName} variable"), null!);
31-
}
32-
33-
protected Func<BaseToken, Func<TValue>?>? AdditionalTokenParser = null;
34-
3525
private bool _equalSignSet = false;
36-
private (RunnableContext main, IMayReturnValueContext returner)? _returnContext = null;
37-
private Func<TValue>? _parser = null;
26+
private ValueExpressionContext? _expression = null;
3827

3928
public override string FriendlyName => $"'{varToken.RawRep}' variable definition";
4029

@@ -52,98 +41,44 @@ public override TryAddTokenRes TryAddToken(BaseToken token)
5241
return TryAddTokenRes.Continue();
5342
}
5443

55-
if (_returnContext != null)
56-
{
57-
return _returnContext.Value.main.TryAddToken(token);
58-
}
59-
60-
var parser = AdditionalTokenParser?.Invoke(token);
61-
if (parser != null)
62-
{
63-
_parser = parser;
64-
return TryAddTokenRes.End();
65-
}
66-
67-
if (token.CanReturn<TValue>(out var get))
44+
if (_expression == null)
6845
{
69-
Log.D("set parser using value capable");
70-
_parser = () =>
46+
_expression = new ValueExpressionContext(token, true)
7147
{
72-
if (get().HasErrored(out var error, out var value))
73-
{
74-
throw new ScriptRuntimeError(this, error);
75-
}
76-
77-
return value;
48+
Script = Script,
49+
ParentContext = this
7850
};
79-
return TryAddTokenRes.End();
80-
}
81-
82-
if (token is IContextableToken contextable &&
83-
contextable.GetContext(Script) is { } mainContext and IMayReturnValueContext returnValueContext)
84-
{
85-
_returnContext = (mainContext, returnValueContext);
8651
return TryAddTokenRes.Continue();
8752
}
88-
89-
Log.D("set parser using additional");
90-
var (result, receivedParser) = AdditionalParsing(token);
91-
_parser = receivedParser;
92-
return result;
53+
54+
return _expression.TryAddToken(token);
9355
}
9456

9557
public override Result VerifyCurrentState()
9658
{
97-
if (_returnContext is {
98-
main: var main,
99-
returner: { Returns: null } returner
100-
})
101-
{
102-
return $"{main} does not return a value. {returner.UndefinedReturnsHint}";
103-
}
104-
105-
return Result.Assert(
106-
_returnContext is not null ||
107-
_parser is not null,
108-
$"Value for variable '{varToken.RawRep}' was not provided."
109-
);
59+
if (!_equalSignSet) return $"Value for variable '{varToken.RawRep}' was not provided (missing equals sign).";
60+
if (_expression is null) return $"Value for variable '{varToken.RawRep}' was not provided.";
61+
return _expression.VerifyCurrentState();
11062
}
11163

11264
protected override IEnumerator<float> Execute()
11365
{
114-
if (_returnContext.HasValue)
115-
{
116-
var (main, returner) = _returnContext.Value;
117-
118-
var coro = main.ExecuteBaseContext();
119-
while (coro.MoveNext())
120-
{
121-
yield return coro.Current;
122-
}
123-
124-
Log.D("checking for returned value");
125-
if (returner.ReturnedValue is not { } value)
126-
{
127-
throw new ScriptRuntimeError(this, $"{main} has not returned a value! {returner.MissingValueHint}");
128-
}
129-
130-
if (value.TryCast<TValue>().HasErrored(out var error, out var tValue))
131-
{
132-
throw new ScriptRuntimeError(this,
133-
$"Value returned by {main} cannot be assigned to the '{varToken.RawRep}' variable: {error}"
134-
);
135-
}
66+
if (_expression is null) throw new AndrzejFuckedUpException();
13667

137-
DefinedVariable = Variable.Create(varToken.Name, tValue);
138-
}
139-
else if (_parser is not null)
68+
var coro = _expression.Run();
69+
while (coro.MoveNext())
14070
{
141-
DefinedVariable = Variable.Create(varToken.Name, Value.Parse(_parser(), Script));
71+
yield return coro.Current;
14272
}
143-
else
73+
74+
if (_expression.GetValue().SuccessTryCast<TValue>().HasErrored(out var error, out var tValue))
14475
{
145-
throw new AndrzejFuckedUpException();
76+
throw new ScriptRuntimeError(this,
77+
$"Value returned by '{FriendlyName}' cannot be assigned to the '{varToken.RawRep}' variable: {error}"
78+
);
14679
}
80+
81+
DefinedVariable = Variable.Create(varToken.Name, tValue);
14782

14883
if (CreateLocalVariable)
14984
Script.AddLocalVariable(DefinedVariable);

Code/ContextSystem/Contexts/WithKeyword.cs

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -27,20 +27,20 @@ public class WithKeyword : StandardContext, IKeywordContext, INotRunningContext,
2727
over @all
2828
with @plr
2929
30-
Print {@plr name}
30+
Print {@plr -> name}
3131
end
3232
3333
# WRONG - "with" keyword does not add indentation
3434
over @all
3535
with @plr
36-
Print {@plr name}
36+
Print {@plr -> name}
3737
end
3838
3939
# WRONG - with keyword is not a statement that can be closed
4040
# this causes an error
4141
# over @all
4242
# with @plr
43-
# Print {@plr name}
43+
# Print {@plr -> name}
4444
# end
4545
# end
4646
""";

0 commit comments

Comments
 (0)