Skip to content

Commit a54f02b

Browse files
improve errors, Script cleanup
1 parent 7614f85 commit a54f02b

5 files changed

Lines changed: 108 additions & 56 deletions

File tree

Code/ContextSystem/Contexter.cs

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -20,24 +20,29 @@ public static TryGet<Context[]> ContextLines(Line[] lines, Script scr)
2020
Stack<StatementContext> statementStack = [];
2121
List<Context> contexts = [];
2222

23+
List<Result> errors = [];
2324
foreach (var line in lines)
2425
{
2526
Result mainErr = $"Line {line.LineNumber} cannot compile.";
2627
if (ContextLine(line.Tokens, line.LineNumber, scr)
2728
.HasErrored(out var error, out var context))
2829
{
29-
return mainErr + error;
30+
errors.Add(mainErr + error);
31+
continue;
3032
}
3133

3234
if (context is null) continue;
3335

3436
if (TryAddResult(context, line.LineNumber, statementStack, contexts).HasErrored(out var addError))
3537
{
36-
return mainErr + addError;
38+
errors.Add(mainErr + addError);
39+
continue;
3740
}
3841
Log.Debug($"current statement stack: {statementStack.Select(s => s.GetType().Name).JoinStrings(" -> ")}");
3942
}
4043

44+
if (errors.Any()) return Result.Merge(errors);
45+
4146
return contexts.ToArray();
4247
}
4348

Code/FileSystem/FileSystem.cs

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@
55
using SER.Code.Examples;
66
using SER.Code.Extensions;
77
using SER.Code.FlagSystem;
8+
using SER.Code.Helpers;
89
using SER.Code.ScriptSystem;
910
using SER.Code.ScriptSystem.Structures;
1011

@@ -62,7 +63,15 @@ public static void Initialize()
6263
{
6364
var scriptName = ScriptName.InitUnchecked(Path.GetFileNameWithoutExtension(scriptPath));
6465

65-
var lines = Script.CreateByVerifiedPath(scriptPath, ServerConsoleExecutor.Instance).GetFlagLines();
66+
if (Script
67+
.CreateByVerifiedPath(scriptPath, ServerConsoleExecutor.Instance)
68+
.GetFlagLines()
69+
.HasErrored(out var error, out var lines))
70+
{
71+
Log.CompileError(error, scriptPath);
72+
continue;
73+
}
74+
6675
if (lines.IsEmpty())
6776
{
6877
continue;

Code/Helpers/ResultSystem/Result.cs

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
using SER.Code.Exceptions;
2+
using SER.Code.Extensions;
23

34
namespace SER.Code.Helpers.ResultSystem;
45

@@ -72,4 +73,9 @@ private static string Process(string value)
7273

7374
return value;
7475
}
76+
77+
public static Result Merge(params IEnumerable<Result> results)
78+
{
79+
return "\n" + results.Select(r => r.ErrorMsg).Select(e => $"| {e}").JoinStrings("\n--------------------------------\n");
80+
}
7581
}

Code/ScriptSystem/Script.cs

Lines changed: 75 additions & 46 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,9 @@
11
using System.Collections.ObjectModel;
2+
<<<<<<< Updated upstream
3+
=======
4+
using System.Runtime.CompilerServices;
5+
using JetBrains.Annotations;
6+
>>>>>>> Stashed changes
27
using LabApi.Features.Wrappers;
38
using SER.Code.ContextSystem;
49
using SER.Code.ContextSystem.BaseContexts;
@@ -10,6 +15,7 @@
1015
using SER.Code.FlagSystem.Flags;
1116
using SER.Code.Helpers;
1217
using SER.Code.Helpers.ResultSystem;
18+
using SER.Code.MethodSystem;
1319
using SER.Code.ScriptSystem.Structures;
1420
using SER.Code.TokenSystem;
1521
using SER.Code.TokenSystem.Structures;
@@ -23,6 +29,10 @@ namespace SER.Code.ScriptSystem;
2329

2430
public class Script
2531
{
32+
private Line[] _lines = [];
33+
private Context[] _contexts = [];
34+
private bool? _isEventAllowed;
35+
2636
public required ScriptName Name { get; init; }
2737

2838
public required string Content { get; init; }
@@ -34,21 +44,22 @@ public required ScriptExecutor Executor
3444
{
3545
switch (value)
3646
{
37-
case RemoteAdminExecutor { Sender: { } sender } when Player.TryGet(sender, out var player):
38-
AddLocalVariable(new PlayerVariable("sender", new([player])));
47+
case RemoteAdminExecutor { Sender: { } sender } when Player.Get(sender) is { } player:
48+
{
49+
AddLocalVariable(new PlayerVariable("sender", new(player)));
3950
break;
40-
case PlayerConsoleExecutor { Sender: { } hub }:
41-
AddLocalVariable(new PlayerVariable("sender", new([Player.Get(hub)])));
51+
}
52+
case PlayerConsoleExecutor { Sender: { } hub } when Player.Get(hub) is { } player:
53+
{
54+
AddLocalVariable(new PlayerVariable("sender", new(player)));
4255
break;
56+
}
4357
}
4458

4559
field = value;
4660
}
4761
}
4862

49-
public Line[] Lines = [];
50-
public Context[] Contexts = [];
51-
5263
public bool Killed { get; private set; }
5364

5465
public Script? Caller { get; private set; }
@@ -57,22 +68,20 @@ public required ScriptExecutor Executor
5768

5869
public RunReason RunReason { get; private set; }
5970

60-
public uint CurrentLine { get; set; } = 0;
61-
62-
private static readonly List<Script> RunningScriptsList = [];
63-
public static readonly ReadOnlyCollection<Script> RunningScripts = RunningScriptsList.AsReadOnly();
71+
public uint CurrentLine { get; set; }
6472

65-
private readonly HashSet<Variable> _localVariables = [];
66-
public ReadOnlyCollection<Variable> LocalVariables => _localVariables.ToList().AsReadOnly();
67-
6873
public DateTime StartTime { get; private set; }
6974

7075
public TimeSpan TimeRunning => StartTime == DateTime.MinValue ? TimeSpan.Zero : DateTime.Now - StartTime;
76+
77+
private static readonly HashSet<Script> RunningScriptsList = [];
78+
public static readonly Script[] RunningScripts = RunningScriptsList.ToArray();
7179

72-
private bool? _isEventAllowed;
80+
private readonly HashSet<Variable> _localVariables = [];
81+
public Variable[] LocalVariables => _localVariables.ToArray();
7382

74-
private readonly Dictionary<string, FunctionDefinitionContext> _definedFunctions = [];
75-
public ReadOnlyDictionary<string, FunctionDefinitionContext> DefinedFunctions => new(_definedFunctions);
83+
private readonly Dictionary<string, FuncStatement> _definedFunctions = [];
84+
public ReadOnlyDictionary<string, FuncStatement> DefinedFunctions => new(_definedFunctions);
7685

7786
public void Reply(string message)
7887
{
@@ -121,7 +130,7 @@ public static TryGet<Script> CreateByScriptName(string dirtyName, ScriptExecutor
121130

122131
public static int StopAll()
123132
{
124-
var count = RunningScripts.Count;
133+
var count = RunningScripts.Length;
125134
foreach (var script in new List<Script>(RunningScripts))
126135
{
127136
script.ExternalStop();
@@ -150,12 +159,30 @@ public bool HasFlag<T>() where T : Flag
150159
return ScriptFlagHandler.ScriptsFlags[Name].Any(f => f is T);
151160
}
152161

153-
public List<Line> GetFlagLines()
162+
public TryGet<List<Line>> GetFlagLines()
154163
{
155164
DefineLines();
156-
SliceLines();
157-
TokenizeLines();
158-
return Lines.Where(l => l.Tokens.FirstOrDefault() is FlagToken or FlagArgumentToken).ToList();
165+
if (SliceLines().HasErrored(out var err) || TokenizeLines().HasErrored(out err))
166+
{
167+
return err;
168+
}
169+
170+
return _lines.Where(l => l.Tokens.FirstOrDefault() is FlagToken or FlagArgumentToken).ToList();
171+
}
172+
173+
/// <summary>
174+
/// Used for external tools to verify the script content.
175+
/// This is NOT to be used in an actual server.
176+
/// </summary>
177+
[UsedImplicitly]
178+
public static string? VerifyForExternalTool(string content)
179+
{
180+
if (MethodIndex.NameToMethodIndex.Count is 0)
181+
{
182+
MethodIndex.Initialize();
183+
}
184+
185+
return CreateAnonymous("test", content).Compile().HasErrored(out var err) ? err : null;
159186
}
160187

161188
/// <summary>
@@ -206,22 +233,16 @@ public void SendControlMessage(ScriptControlMessage msg)
206233
}
207234
}
208235

209-
public Result DefineLines()
236+
public void DefineLines()
210237
{
211238
var prof = Profile is not null
212239
? new Profile(Profile, nameof(DefineLines))
213240
: null;
214241

215-
if (Tokenizer.GetInfoFromMultipleLines(Content).HasErrored(out var err, out var info))
216-
{
217-
return "Defining script lines failed." + err;
218-
}
242+
_lines = Tokenizer.GetInfoFromMultipleLines(Content);
219243

244+
Log.Debug($"Script {Name} defines {_lines.Length} lines");
220245
prof?.Stop();
221-
222-
Log.Debug($"Script {Name} defines {info.Length} lines");
223-
Lines = info;
224-
return true;
225246
}
226247

227248
public Result SliceLines()
@@ -230,18 +251,24 @@ public Result SliceLines()
230251
? new Profile(Profile, nameof(SliceLines))
231252
: null;
232253

233-
foreach (var line in Lines)
254+
List<Result> errors = [];
255+
foreach (var line in _lines)
234256
{
235257
if (Tokenizer.SliceLine(line).HasErrored(out var error))
236258
{
237-
Result mainErr = $"Processing line {line.LineNumber} has failed.";
238-
return mainErr + error;
259+
errors.Add(error);
239260
}
240261
}
262+
263+
if (errors.Any())
264+
{
265+
return Result.Merge(errors);
266+
}
241267

242268
prof?.Stop();
243269

244-
Log.Debug($"Script {Name} sliced {Lines.Length} lines into {Lines.Sum(l => l.Slices.Length)} slices");
270+
Log.Debug($"Script {Name} sliced {_lines.Length} lines into {_lines.Sum(l => l.Slices.Length)} slices");
271+
245272
return true;
246273
}
247274

@@ -251,21 +278,23 @@ public Result TokenizeLines()
251278
? new Profile(Profile, nameof(TokenizeLines))
252279
: null;
253280

254-
foreach (var line in Lines)
281+
List<Result> errors = [];
282+
foreach (var line in _lines)
255283
{
256284
if (Tokenizer.TokenizeLine(line, this).HasErrored(out var error))
257285
{
258-
return error;
286+
errors.Add(error);
259287
}
260288
}
261289

262290
prof?.Stop();
291+
if (errors.Any()) return Result.Merge(errors);
263292

264-
Log.Debug($"Script {Name} tokenized {Lines.Length} lines into {Lines.Sum(l => l.Tokens.Length)} tokens");
293+
Log.Debug($"Script {Name} tokenized {_lines.Length} lines into {_lines.Sum(l => l.Tokens.Length)} tokens");
265294
return true;
266295
}
267296

268-
public void DefineFunction(string name, FunctionDefinitionContext context)
297+
public void DefineFunction(string name, FuncStatement context)
269298
=> _definedFunctions.Add(name, context);
270299

271300
private Result ContextLines()
@@ -274,23 +303,23 @@ private Result ContextLines()
274303
? new Profile(Profile, nameof(ContextLines))
275304
: null;
276305

277-
if (Contexter.ContextLines(Lines, this).HasErrored(out var err, out var contexts))
306+
if (Contexter.ContextLines(_lines, this).HasErrored(out var err, out var contexts))
278307
{
279308
return err;
280309
}
281310

282311
prof?.Stop();
283312

284-
Contexts = contexts;
313+
_contexts = contexts;
285314
return true;
286315
}
287316

288317
public Result Compile()
289318
{
290-
if (DefineLines().HasErrored(out var err) ||
291-
SliceLines().HasErrored(out err) ||
292-
TokenizeLines().HasErrored(out err) ||
293-
ContextLines().HasErrored(out err))
319+
DefineLines();
320+
if (SliceLines().HasErrored(out var err) ||
321+
TokenizeLines().HasErrored(out err) ||
322+
ContextLines().HasErrored(out err))
294323
{
295324
return err;
296325
}
@@ -305,7 +334,7 @@ private IEnumerator<float> InternalExecute()
305334
throw new ScriptCompileError(err);
306335
}
307336

308-
foreach (var context in Contexts)
337+
foreach (var context in _contexts)
309338
{
310339
var handle = context.ExecuteBaseContext();
311340
while (handle.MoveNext())

Code/TokenSystem/Tokenizer.cs

Lines changed: 10 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -40,7 +40,7 @@ public static class Tokenizer
4040
typeof(TextToken)
4141
];
4242

43-
public static TryGet<Line[]> GetInfoFromMultipleLines(string content)
43+
public static Line[] GetInfoFromMultipleLines(string content)
4444
{
4545
List<Line> outList = [];
4646

@@ -148,15 +148,18 @@ public static TryGet<BaseToken[]> TokenizeLine(string line, Script scr, uint? li
148148
public static TryGet<BaseToken[]> TokenizeLine(IEnumerable<Slice> slices, Script scr, uint? lineNum)
149149
{
150150
var sliceArray = slices.ToArray();
151-
var tokens = sliceArray.Select(slice => GetTokenFromSlice(slice, scr, lineNum)).ToArray();
152-
153-
var error = tokens.FirstOrDefault(t => t.HasErrored(out _))?.ErrorMsg;
154-
if (error is not null)
151+
List<BaseToken> outList = [];
152+
foreach (var slice in sliceArray)
155153
{
156-
return error;
154+
if (GetTokenFromSlice(slice, scr, lineNum).HasErrored(out var error, out var token))
155+
{
156+
return error;
157+
}
158+
159+
outList.Add(token);
157160
}
158161

159-
return tokens.Select(t => t.Value!).ToArray();
162+
return outList.ToArray();
160163
}
161164

162165
public static TryGet<BaseToken> GetTokenFromSlice(Slice slice, Script? scr, uint? lineNum)

0 commit comments

Comments
 (0)