-
Notifications
You must be signed in to change notification settings - Fork 14
/
Copy pathScriptLoader.java
151 lines (141 loc) · 6.07 KB
/
ScriptLoader.java
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
package io.github.syst3ms.skriptparser.parsing;
import io.github.syst3ms.skriptparser.file.FileElement;
import io.github.syst3ms.skriptparser.file.FileParser;
import io.github.syst3ms.skriptparser.file.FileSection;
import io.github.syst3ms.skriptparser.file.VoidElement;
import io.github.syst3ms.skriptparser.lang.SkriptEvent;
import io.github.syst3ms.skriptparser.lang.Statement;
import io.github.syst3ms.skriptparser.lang.Trigger;
import io.github.syst3ms.skriptparser.lang.UnloadedTrigger;
import io.github.syst3ms.skriptparser.log.ErrorType;
import io.github.syst3ms.skriptparser.log.LogEntry;
import io.github.syst3ms.skriptparser.log.SkriptLogger;
import io.github.syst3ms.skriptparser.util.FileUtils;
import io.github.syst3ms.skriptparser.util.MultiMap;
import java.io.IOException;
import java.nio.file.Path;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
/**
* Contains the logic for loading, parsing and interpreting entire script files
*/
public class ScriptLoader {
private static final MultiMap<String, Trigger> triggerMap = new MultiMap<>();
/**
* Parses and loads the provided script in memory.
*
* @param scriptPath the script file to load.
* @param debug whether debug is enabled.
*/
public static List<LogEntry> loadScript(Path scriptPath, boolean debug) {
return loadScript(scriptPath, new SkriptLogger(debug), debug);
}
/**
* Parses and loads the provided script in memory.
* The provided SkriptLogger can be used within syntaxes to input erroring into the logs during parse time.
*
* @param scriptPath the script file to load.
* @param logger The {@link SkriptLogger} to use for the logged entries. Useful for custom logging.
* @param debug whether debug is enabled.
*/
public static List<LogEntry> loadScript(Path scriptPath, SkriptLogger logger, boolean debug) {
List<FileElement> elements;
String scriptName;
try {
var lines = FileUtils.readAllLines(scriptPath);
scriptName = scriptPath.getFileName().toString().replaceAll("(.+)\\..+", "$1");
elements = FileParser.parseFileLines(scriptName,
lines,
0,
1,
logger
);
logger.finalizeLogs();
} catch (IOException e) {
e.printStackTrace();
return Collections.emptyList();
}
logger.setFileInfo(scriptPath.getFileName().toString(), elements);
List<UnloadedTrigger> unloadedTriggers = new ArrayList<>();
for (var element : elements) {
logger.finalizeLogs();
logger.nextLine();
if (element instanceof VoidElement)
continue;
if (element instanceof FileSection) {
var trig = SyntaxParser.parseTrigger((FileSection) element, logger);
trig.ifPresent(t -> {
logger.setLine(logger.getLine() + ((FileSection) element).length());
unloadedTriggers.add(t);
//SkriptEvent skriptEvent = t.getTrigger().getEvent();
/* TODO
validate that this is a function
parse & save it
have a separate parser to parse a whole folder that does this step before anything
*/
//System.out.println(skriptEvent);
});
} else {
logger.error(
"Can't have code outside of a trigger",
ErrorType.STRUCTURE_ERROR,
"Code always starts with a trigger (or event). Refer to the documentation to see which event you need, or indent this line so it is part of a trigger"
);
}
}
unloadedTriggers.sort((a, b) -> b.getTrigger().getEvent().getLoadingPriority() - a.getTrigger().getEvent().getLoadingPriority());
for (var unloaded : unloadedTriggers) {
logger.finalizeLogs();
logger.setLine(unloaded.getLine());
var loaded = unloaded.getTrigger();
loaded.loadSection(unloaded.getSection(), unloaded.getParserState(), logger);
unloaded.getEventInfo().getRegisterer().handleTrigger(loaded);
triggerMap.putOne(scriptName, loaded);
}
logger.finalizeLogs();
return logger.close();
}
/**
* Parses all items inside of a given section.
* @param section the section
* @param logger the logger
* @return a list of {@linkplain Statement effects} inside of the section
*/
public static List<Statement> loadItems(FileSection section, ParserState parserState, SkriptLogger logger) {
logger.recurse();
parserState.recurseCurrentStatements();
List<Statement> items = new ArrayList<>();
var elements = section.getElements();
for (var element : elements) {
logger.finalizeLogs();
logger.nextLine();
if (element instanceof VoidElement)
continue;
if (element instanceof FileSection) {
var codeSection = SyntaxParser.parseSection((FileSection) element, parserState, logger);
if (codeSection.isEmpty()) {
continue;
}
parserState.addCurrentStatement(codeSection.get());
items.add(codeSection.get());
} else {
var statement = SyntaxParser.parseEffect(element.getLineContent(), parserState, logger);
if (statement.isEmpty())
continue;
parserState.addCurrentStatement(statement.get());
items.add(statement.get());
}
}
logger.finalizeLogs();
for (var i = items.size() - 1; i > 0; i--) {
items.get(i - 1).setNext(items.get(i));
}
logger.callback();
parserState.callbackCurrentStatements();
return items;
}
public static MultiMap<String, Trigger> getTriggerMap() {
return triggerMap;
}
}