Skip to content

Commit

Permalink
Correct type expression and improve debug mode.
Browse files Browse the repository at this point in the history
  • Loading branch information
Moderocky committed Mar 10, 2022
1 parent c353461 commit 32a0741
Show file tree
Hide file tree
Showing 9 changed files with 125 additions and 71 deletions.
2 changes: 1 addition & 1 deletion docs/index.html

Large diffs are not rendered by default.

Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,9 @@ public void compile(Context context, Pattern.Match match) throws Throwable {

@Override
public void onSectionExit(Context context, SectionMeta meta) {
final ProgrammaticSplitTree current = context.getCurrentTree();
final ProgrammaticSplitTree current;
if (context.getTree(context.getSection()) instanceof ExtractionTree found) current = found;
else current = context.getCurrentTree();
if (!(current instanceof ExtractionTree tree))
throw new ScriptCompileError(context.lineNumber(), "Unable to close section flow tree.");
context.setState(CompileState.CODE_BODY);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -56,6 +56,11 @@ public PostCompileClass[] compile(String source, Type path) {
return super.compile(source, path);
}

@Override
protected FileContext createContext(Type path) {
return new FileContext(path, 0);
}

protected void debug(ElementTree tree, FileContext context) {
try {
this.controller.write("\n");
Expand Down
18 changes: 16 additions & 2 deletions src/main/java/org/byteskript/skript/compiler/FileContext.java
Original file line number Diff line number Diff line change
Expand Up @@ -47,6 +47,10 @@ public class FileContext extends Context {
private HandlerType mode = StandardHandlers.GET;

public FileContext(Type type) {
this(type, -1);
}

public FileContext(Type type, int computation) {
this.type = type;
this.state = CompileState.ROOT;
this.writer = new ClassBuilder(type, SkriptLangSpec.JAVA_VERSION)
Expand All @@ -55,7 +59,7 @@ public FileContext(Type type) {
.setSuperclass(CompiledScript.class);
this.addSkriptFunctions();
this.registerType("none", new Type(void.class)); // special overridden case
// writer.setComputation(1); // todo
if (computation > -1) writer.setComputation(computation);
}

private void addSkriptFunctions() {
Expand Down Expand Up @@ -85,7 +89,17 @@ public PostCompileClass[] compile() {
final List<PostCompileClass> classes = new ArrayList<>();
classes.add(new PostCompileClass(writer.compile(), writer.getName(), writer.getInternalName()));
for (ClassBuilder builder : writer.getSuppressed()) {
classes.add(new PostCompileClass(builder.compile(), builder.getName(), builder.getInternalName()));
try {
classes.add(new PostCompileClass(builder.compile(), builder.getName(), builder.getInternalName()));
} catch (ArrayIndexOutOfBoundsException ex) {
if (ex.getStackTrace()[0].getClassName().endsWith("Frame")) {
throw new ScriptCompileError(-1, """
Error during assembly phase.
This error cannot be directly triaged, but likely comes from a malformed syntax (in which case the library-maintainer needs to fix it.)
Experienced developers may check the `debug` output to see where the stack calculation error is.
""");
}
}
}
return classes.toArray(new PostCompileClass[0]);
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -299,7 +299,7 @@ public boolean removeLibrary(Library library) {

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

@Override
public PostCompileClass[] compile(String source, Type path) {
final FileContext context = new FileContext(path);
final FileContext context = this.createContext(path);
context.libraries.addAll(libraries);
for (final Library library : libraries) {
for (final Type type : library.getTypes()) context.registerType(type);
Expand All @@ -351,6 +351,10 @@ public SimpleSkriptCompiler clone() {
return compiler;
}

protected FileContext createContext(Type path) {
return new FileContext(path);
}

private void compileLine(FileContext context, String stripped) {
if (context.getMethod() != null) {
context.getMethod().writeCode(WriteInstruction.lineNumber(context.lineNumber));
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@
import mx.kenzie.foundation.Type;
import mx.kenzie.foundation.WriteInstruction;
import org.byteskript.skript.api.note.Documentation;
import org.byteskript.skript.api.syntax.SimpleExpression;
import org.byteskript.skript.api.syntax.Literal;
import org.byteskript.skript.compiler.CommonTypes;
import org.byteskript.skript.compiler.Context;
import org.byteskript.skript.compiler.Pattern;
Expand All @@ -36,26 +36,34 @@ Gets the (class) handle for a type, using its fully-qualified name.
"""
}
)
public class TypeExpression extends SimpleExpression {
public class TypeExpression extends Literal<Class<?>> {

private final java.util.regex.Pattern pattern = java.util.regex.Pattern.compile("^\\p{javaJavaIdentifierStart}[\\p{javaJavaIdentifierPart}./]+$");

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

@Override
public Type getReturnType() {
return CommonTypes.CLASS;
}

@Override
public void compile(Context context, Pattern.Match match) throws Throwable {
final MethodBuilder method = context.getMethod();
assert method != null;
method.writeCode(WriteInstruction.loadClassConstant(match.meta()));
}

@Override
public Class<?> parse(String input) {
try {
return Class.forName(input.replace('/', '.'));
} catch (ClassNotFoundException e) {
return null;
}
}

@Override
public Pattern.Match match(String thing, Context context) {
if (thing.contains("\"")) return null;
if (!pattern.matcher(thing).matches()) return null;
final Type type = this.getType(thing, context);
if (type == null) return null;
final Matcher matcher = Pattern.fakeMatcher(thing);
Expand All @@ -67,6 +75,11 @@ public boolean allowAsInputFor(Type type) {
return CommonTypes.CLASS.equals(type) || CommonTypes.TYPE.equals(type) || CommonTypes.OBJECT.equals(type);
}

@Override
public Type getReturnType() {
return CommonTypes.CLASS;
}

public Type getType(String string, Context context) {
for (final Map.Entry<String, Type> entry : context.getTypeMap().entrySet()) {
if (!entry.getKey().toLowerCase(Locale.ROOT).equals(string.toLowerCase(Locale.ROOT))) continue;
Expand Down
122 changes: 64 additions & 58 deletions src/main/java/org/byteskript/skript/runtime/config/ConfigMap.java
Original file line number Diff line number Diff line change
Expand Up @@ -41,64 +41,6 @@ public ConfigMap(File file) throws IOException {
}
}

protected void readLines(InputStreamController controller) {
final AtomicBoolean comment = new AtomicBoolean(false);
for (final String thing : controller.lines()) {
final String line = this.stripLine(thing, comment);
if (line.isEmpty()) continue;
final int index = line.indexOf(':');
if (index < 0) continue;
final ConfigEntry entry = new ConfigEntry();
entry.comments = comments.toArray(new String[0]);
entry.key = line.substring(0, index).trim();
entry.value = line.substring(index + 1).trim();
this.put(entry);
this.comments.clear();
}

}

protected String stripLine(final String old, AtomicBoolean comment) {
String line = old;
boolean started = false;
do {
if (!comment.get()) {
if (line.contains("//")) {
final String string = line.substring(line.indexOf("//") + 2).trim();
line = line.substring(0, line.indexOf("//")); // keep first part of line
this.comments.add(string);
}
if (line.contains("/*")) {
started = true;
comment.set(true);
final String string = line.substring(line.indexOf("/*") + 2);
line = line.substring(0, line.indexOf("/*")); // first part of line not in comment
this.current.append(string);
}
}
if (comment.get()) {
if (line.contains("*/")) {
if (!started) this.current.append(System.lineSeparator());
final String string = line.substring(0, line.indexOf("*/"));
line = line.substring(line.indexOf("*/") + 2); // keep last part of line
this.current.append(string);
this.comments.add(current.toString().trim());
this.current = new StringBuilder();
comment.set(false);
} else {
if (!started) this.current.append(System.lineSeparator());
this.current.append(line);
line = ""; // inside a commented block
}
}
} while (line.contains("/*") || line.contains("*/") || line.contains("//"));
return line.trim(); // for now just trim lines, no indented areas
}

public ConfigEntry put(ConfigEntry value) {
return super.put(value.key, value);
}

public ConfigMap(InputStream stream) throws IOException {
this.file = null;
try (final InputStreamController controller = Stream.controller(stream)) {
Expand Down Expand Up @@ -164,6 +106,70 @@ public static void deleteMapValue(Object key, Object target) {
set(key + "", map, null);
}

protected void readLines(InputStreamController controller) {
final AtomicBoolean comment = new AtomicBoolean(false);
for (final String thing : controller.lines()) {
final String line = this.stripLine(thing, comment);
if (line.isEmpty()) continue;
final int index = this.findSplitter(line, 0);
if (index < 0) continue;
final ConfigEntry entry = new ConfigEntry();
entry.comments = comments.toArray(new String[0]);
entry.key = line.substring(0, index).trim();
entry.value = line.substring(index + 1).trim();
this.put(entry);
this.comments.clear();
}
}

private int findSplitter(String line, int from) {
final int index = line.indexOf(':', from);
if (index < 1) return -1; // illegal :line
if (line.charAt(index - 1) != '\\') return index;
return this.findSplitter(line, index); // ke\:y: value
}

protected String stripLine(final String old, AtomicBoolean comment) {
String line = old;
boolean started = false;
do {
if (!comment.get()) {
if (line.contains("//")) {
final String string = line.substring(line.indexOf("//") + 2).trim();
line = line.substring(0, line.indexOf("//")); // keep first part of line
this.comments.add(string);
}
if (line.contains("/*")) {
started = true;
comment.set(true);
final String string = line.substring(line.indexOf("/*") + 2);
line = line.substring(0, line.indexOf("/*")); // first part of line not in comment
this.current.append(string);
}
}
if (comment.get()) {
if (line.contains("*/")) {
if (!started) this.current.append(System.lineSeparator());
final String string = line.substring(0, line.indexOf("*/"));
line = line.substring(line.indexOf("*/") + 2); // keep last part of line
this.current.append(string);
this.comments.add(current.toString().trim());
this.current = new StringBuilder();
comment.set(false);
} else {
if (!started) this.current.append(System.lineSeparator());
this.current.append(line);
line = ""; // inside a commented block
}
}
} while (line.contains("/*") || line.contains("*/") || line.contains("//"));
return line.trim(); // for now just trim lines, no indented areas
}

public ConfigEntry put(ConfigEntry value) {
return super.put(value.key, value);
}

public void delete() {
if (file == null) return;
this.file.delete();
Expand Down
1 change: 1 addition & 0 deletions src/test/java/org/byteskript/skript/test/FlowTest.java
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@ public class FlowTest extends SkriptTest {
public static void start() throws Throwable {
final PostCompileClass cls = skript.compileScript(FlowTest.class.getClassLoader()
.getResourceAsStream("flow.bsk"), "skript.flow");
debug(cls); //todo
script = skript.loadScript(cls);
}

Expand Down
9 changes: 9 additions & 0 deletions src/test/resources/flow.bsk
Original file line number Diff line number Diff line change
Expand Up @@ -97,6 +97,15 @@ function while_flow:
while {count} is less than 10:
set {count} to {count} + 1
assert {count} is 10: "While loop failed to count properly."
set {var} to a new runnable:
set {count} to 0
while {count} < 10:
set {phase} to {count} as a string
set {tag} to "a" + {phase}
assert {tag} is a string
set {count} to {count} + 1
assert true is true // todo - currently un-fixable
run {var}
return "ended"

function test_run:
Expand Down

0 comments on commit 32a0741

Please sign in to comment.