Skip to content

Commit 32a0741

Browse files
committed
Correct type expression and improve debug mode.
1 parent c353461 commit 32a0741

File tree

9 files changed

+125
-71
lines changed

9 files changed

+125
-71
lines changed

docs/index.html

Lines changed: 1 addition & 1 deletion
Large diffs are not rendered by default.

src/main/java/org/byteskript/skript/api/syntax/ExtractedSection.java

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -35,7 +35,9 @@ public void compile(Context context, Pattern.Match match) throws Throwable {
3535

3636
@Override
3737
public void onSectionExit(Context context, SectionMeta meta) {
38-
final ProgrammaticSplitTree current = context.getCurrentTree();
38+
final ProgrammaticSplitTree current;
39+
if (context.getTree(context.getSection()) instanceof ExtractionTree found) current = found;
40+
else current = context.getCurrentTree();
3941
if (!(current instanceof ExtractionTree tree))
4042
throw new ScriptCompileError(context.lineNumber(), "Unable to close section flow tree.");
4143
context.setState(CompileState.CODE_BODY);

src/main/java/org/byteskript/skript/compiler/DebugSkriptCompiler.java

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -56,6 +56,11 @@ public PostCompileClass[] compile(String source, Type path) {
5656
return super.compile(source, path);
5757
}
5858

59+
@Override
60+
protected FileContext createContext(Type path) {
61+
return new FileContext(path, 0);
62+
}
63+
5964
protected void debug(ElementTree tree, FileContext context) {
6065
try {
6166
this.controller.write("\n");

src/main/java/org/byteskript/skript/compiler/FileContext.java

Lines changed: 16 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -47,6 +47,10 @@ public class FileContext extends Context {
4747
private HandlerType mode = StandardHandlers.GET;
4848

4949
public FileContext(Type type) {
50+
this(type, -1);
51+
}
52+
53+
public FileContext(Type type, int computation) {
5054
this.type = type;
5155
this.state = CompileState.ROOT;
5256
this.writer = new ClassBuilder(type, SkriptLangSpec.JAVA_VERSION)
@@ -55,7 +59,7 @@ public FileContext(Type type) {
5559
.setSuperclass(CompiledScript.class);
5660
this.addSkriptFunctions();
5761
this.registerType("none", new Type(void.class)); // special overridden case
58-
// writer.setComputation(1); // todo
62+
if (computation > -1) writer.setComputation(computation);
5963
}
6064

6165
private void addSkriptFunctions() {
@@ -85,7 +89,17 @@ public PostCompileClass[] compile() {
8589
final List<PostCompileClass> classes = new ArrayList<>();
8690
classes.add(new PostCompileClass(writer.compile(), writer.getName(), writer.getInternalName()));
8791
for (ClassBuilder builder : writer.getSuppressed()) {
88-
classes.add(new PostCompileClass(builder.compile(), builder.getName(), builder.getInternalName()));
92+
try {
93+
classes.add(new PostCompileClass(builder.compile(), builder.getName(), builder.getInternalName()));
94+
} catch (ArrayIndexOutOfBoundsException ex) {
95+
if (ex.getStackTrace()[0].getClassName().endsWith("Frame")) {
96+
throw new ScriptCompileError(-1, """
97+
Error during assembly phase.
98+
This error cannot be directly triaged, but likely comes from a malformed syntax (in which case the library-maintainer needs to fix it.)
99+
Experienced developers may check the `debug` output to see where the stack calculation error is.
100+
""");
101+
}
102+
}
89103
}
90104
return classes.toArray(new PostCompileClass[0]);
91105
}

src/main/java/org/byteskript/skript/compiler/SimpleSkriptCompiler.java

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -299,7 +299,7 @@ public boolean removeLibrary(Library library) {
299299

300300
@Override
301301
public PostCompileClass[] compile(InputStream stream, Type path) {
302-
final FileContext context = new FileContext(path);
302+
final FileContext context = this.createContext(path);
303303
context.libraries.addAll(libraries);
304304
for (final Library library : libraries) {
305305
for (final Type type : library.getTypes()) context.registerType(type);
@@ -325,7 +325,7 @@ public PostCompileClass[] compile(InputStream source, String path) {
325325

326326
@Override
327327
public PostCompileClass[] compile(String source, Type path) {
328-
final FileContext context = new FileContext(path);
328+
final FileContext context = this.createContext(path);
329329
context.libraries.addAll(libraries);
330330
for (final Library library : libraries) {
331331
for (final Type type : library.getTypes()) context.registerType(type);
@@ -351,6 +351,10 @@ public SimpleSkriptCompiler clone() {
351351
return compiler;
352352
}
353353

354+
protected FileContext createContext(Type path) {
355+
return new FileContext(path);
356+
}
357+
354358
private void compileLine(FileContext context, String stripped) {
355359
if (context.getMethod() != null) {
356360
context.getMethod().writeCode(WriteInstruction.lineNumber(context.lineNumber));

src/main/java/org/byteskript/skript/lang/syntax/type/TypeExpression.java

Lines changed: 20 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@
1010
import mx.kenzie.foundation.Type;
1111
import mx.kenzie.foundation.WriteInstruction;
1212
import org.byteskript.skript.api.note.Documentation;
13-
import org.byteskript.skript.api.syntax.SimpleExpression;
13+
import org.byteskript.skript.api.syntax.Literal;
1414
import org.byteskript.skript.compiler.CommonTypes;
1515
import org.byteskript.skript.compiler.Context;
1616
import org.byteskript.skript.compiler.Pattern;
@@ -36,26 +36,34 @@ Gets the (class) handle for a type, using its fully-qualified name.
3636
"""
3737
}
3838
)
39-
public class TypeExpression extends SimpleExpression {
39+
public class TypeExpression extends Literal<Class<?>> {
40+
41+
private final java.util.regex.Pattern pattern = java.util.regex.Pattern.compile("^\\p{javaJavaIdentifierStart}[\\p{javaJavaIdentifierPart}./]+$");
4042

4143
public TypeExpression() {
4244
super(SkriptLangSpec.LIBRARY, StandardElements.EXPRESSION, "type");
4345
}
4446

45-
@Override
46-
public Type getReturnType() {
47-
return CommonTypes.CLASS;
48-
}
49-
5047
@Override
5148
public void compile(Context context, Pattern.Match match) throws Throwable {
5249
final MethodBuilder method = context.getMethod();
5350
assert method != null;
5451
method.writeCode(WriteInstruction.loadClassConstant(match.meta()));
5552
}
5653

54+
@Override
55+
public Class<?> parse(String input) {
56+
try {
57+
return Class.forName(input.replace('/', '.'));
58+
} catch (ClassNotFoundException e) {
59+
return null;
60+
}
61+
}
62+
5763
@Override
5864
public Pattern.Match match(String thing, Context context) {
65+
if (thing.contains("\"")) return null;
66+
if (!pattern.matcher(thing).matches()) return null;
5967
final Type type = this.getType(thing, context);
6068
if (type == null) return null;
6169
final Matcher matcher = Pattern.fakeMatcher(thing);
@@ -67,6 +75,11 @@ public boolean allowAsInputFor(Type type) {
6775
return CommonTypes.CLASS.equals(type) || CommonTypes.TYPE.equals(type) || CommonTypes.OBJECT.equals(type);
6876
}
6977

78+
@Override
79+
public Type getReturnType() {
80+
return CommonTypes.CLASS;
81+
}
82+
7083
public Type getType(String string, Context context) {
7184
for (final Map.Entry<String, Type> entry : context.getTypeMap().entrySet()) {
7285
if (!entry.getKey().toLowerCase(Locale.ROOT).equals(string.toLowerCase(Locale.ROOT))) continue;

src/main/java/org/byteskript/skript/runtime/config/ConfigMap.java

Lines changed: 64 additions & 58 deletions
Original file line numberDiff line numberDiff line change
@@ -41,64 +41,6 @@ public ConfigMap(File file) throws IOException {
4141
}
4242
}
4343

44-
protected void readLines(InputStreamController controller) {
45-
final AtomicBoolean comment = new AtomicBoolean(false);
46-
for (final String thing : controller.lines()) {
47-
final String line = this.stripLine(thing, comment);
48-
if (line.isEmpty()) continue;
49-
final int index = line.indexOf(':');
50-
if (index < 0) continue;
51-
final ConfigEntry entry = new ConfigEntry();
52-
entry.comments = comments.toArray(new String[0]);
53-
entry.key = line.substring(0, index).trim();
54-
entry.value = line.substring(index + 1).trim();
55-
this.put(entry);
56-
this.comments.clear();
57-
}
58-
59-
}
60-
61-
protected String stripLine(final String old, AtomicBoolean comment) {
62-
String line = old;
63-
boolean started = false;
64-
do {
65-
if (!comment.get()) {
66-
if (line.contains("//")) {
67-
final String string = line.substring(line.indexOf("//") + 2).trim();
68-
line = line.substring(0, line.indexOf("//")); // keep first part of line
69-
this.comments.add(string);
70-
}
71-
if (line.contains("/*")) {
72-
started = true;
73-
comment.set(true);
74-
final String string = line.substring(line.indexOf("/*") + 2);
75-
line = line.substring(0, line.indexOf("/*")); // first part of line not in comment
76-
this.current.append(string);
77-
}
78-
}
79-
if (comment.get()) {
80-
if (line.contains("*/")) {
81-
if (!started) this.current.append(System.lineSeparator());
82-
final String string = line.substring(0, line.indexOf("*/"));
83-
line = line.substring(line.indexOf("*/") + 2); // keep last part of line
84-
this.current.append(string);
85-
this.comments.add(current.toString().trim());
86-
this.current = new StringBuilder();
87-
comment.set(false);
88-
} else {
89-
if (!started) this.current.append(System.lineSeparator());
90-
this.current.append(line);
91-
line = ""; // inside a commented block
92-
}
93-
}
94-
} while (line.contains("/*") || line.contains("*/") || line.contains("//"));
95-
return line.trim(); // for now just trim lines, no indented areas
96-
}
97-
98-
public ConfigEntry put(ConfigEntry value) {
99-
return super.put(value.key, value);
100-
}
101-
10244
public ConfigMap(InputStream stream) throws IOException {
10345
this.file = null;
10446
try (final InputStreamController controller = Stream.controller(stream)) {
@@ -164,6 +106,70 @@ public static void deleteMapValue(Object key, Object target) {
164106
set(key + "", map, null);
165107
}
166108

109+
protected void readLines(InputStreamController controller) {
110+
final AtomicBoolean comment = new AtomicBoolean(false);
111+
for (final String thing : controller.lines()) {
112+
final String line = this.stripLine(thing, comment);
113+
if (line.isEmpty()) continue;
114+
final int index = this.findSplitter(line, 0);
115+
if (index < 0) continue;
116+
final ConfigEntry entry = new ConfigEntry();
117+
entry.comments = comments.toArray(new String[0]);
118+
entry.key = line.substring(0, index).trim();
119+
entry.value = line.substring(index + 1).trim();
120+
this.put(entry);
121+
this.comments.clear();
122+
}
123+
}
124+
125+
private int findSplitter(String line, int from) {
126+
final int index = line.indexOf(':', from);
127+
if (index < 1) return -1; // illegal :line
128+
if (line.charAt(index - 1) != '\\') return index;
129+
return this.findSplitter(line, index); // ke\:y: value
130+
}
131+
132+
protected String stripLine(final String old, AtomicBoolean comment) {
133+
String line = old;
134+
boolean started = false;
135+
do {
136+
if (!comment.get()) {
137+
if (line.contains("//")) {
138+
final String string = line.substring(line.indexOf("//") + 2).trim();
139+
line = line.substring(0, line.indexOf("//")); // keep first part of line
140+
this.comments.add(string);
141+
}
142+
if (line.contains("/*")) {
143+
started = true;
144+
comment.set(true);
145+
final String string = line.substring(line.indexOf("/*") + 2);
146+
line = line.substring(0, line.indexOf("/*")); // first part of line not in comment
147+
this.current.append(string);
148+
}
149+
}
150+
if (comment.get()) {
151+
if (line.contains("*/")) {
152+
if (!started) this.current.append(System.lineSeparator());
153+
final String string = line.substring(0, line.indexOf("*/"));
154+
line = line.substring(line.indexOf("*/") + 2); // keep last part of line
155+
this.current.append(string);
156+
this.comments.add(current.toString().trim());
157+
this.current = new StringBuilder();
158+
comment.set(false);
159+
} else {
160+
if (!started) this.current.append(System.lineSeparator());
161+
this.current.append(line);
162+
line = ""; // inside a commented block
163+
}
164+
}
165+
} while (line.contains("/*") || line.contains("*/") || line.contains("//"));
166+
return line.trim(); // for now just trim lines, no indented areas
167+
}
168+
169+
public ConfigEntry put(ConfigEntry value) {
170+
return super.put(value.key, value);
171+
}
172+
167173
public void delete() {
168174
if (file == null) return;
169175
this.file.delete();

src/test/java/org/byteskript/skript/test/FlowTest.java

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,7 @@ public class FlowTest extends SkriptTest {
2222
public static void start() throws Throwable {
2323
final PostCompileClass cls = skript.compileScript(FlowTest.class.getClassLoader()
2424
.getResourceAsStream("flow.bsk"), "skript.flow");
25+
debug(cls); //todo
2526
script = skript.loadScript(cls);
2627
}
2728

src/test/resources/flow.bsk

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -97,6 +97,15 @@ function while_flow:
9797
while {count} is less than 10:
9898
set {count} to {count} + 1
9999
assert {count} is 10: "While loop failed to count properly."
100+
set {var} to a new runnable:
101+
set {count} to 0
102+
while {count} < 10:
103+
set {phase} to {count} as a string
104+
set {tag} to "a" + {phase}
105+
assert {tag} is a string
106+
set {count} to {count} + 1
107+
assert true is true // todo - currently un-fixable
108+
run {var}
100109
return "ended"
101110

102111
function test_run:

0 commit comments

Comments
 (0)