From 993f0bc6b73a4559c11a85e8b86879f0156bd637 Mon Sep 17 00:00:00 2001 From: JFronny Date: Sun, 12 Mar 2023 19:22:45 +0100 Subject: [PATCH] muScript: two fixes for decompiling --- .../jfronny/muscript/ast/dynamic/Call.java | 3 +- .../muscript/compiler/Decompilable.java | 4 +-- .../jfronny/muscript/compiler/ExprWriter.java | 16 ++++++--- .../muscript/data/dynamic/Dynamic.java | 2 +- .../jfronny/muscript/test/DecompileTest.java | 34 +++++++++++++++++++ 5 files changed, 50 insertions(+), 9 deletions(-) create mode 100644 muscript/src/test/java/io/gitlab/jfronny/muscript/test/DecompileTest.java diff --git a/muscript/src/main/java/io/gitlab/jfronny/muscript/ast/dynamic/Call.java b/muscript/src/main/java/io/gitlab/jfronny/muscript/ast/dynamic/Call.java index 9950ec4..81d7373 100644 --- a/muscript/src/main/java/io/gitlab/jfronny/muscript/ast/dynamic/Call.java +++ b/muscript/src/main/java/io/gitlab/jfronny/muscript/ast/dynamic/Call.java @@ -68,7 +68,7 @@ public class Call extends DynamicExpr { writer.decreaseIndent(); writer.append("\n)"); } else { - writer.append("("); + writer.append('('); boolean first = true; for (Arg arg : args) { if (!first) writer.append(", "); @@ -76,6 +76,7 @@ public class Call extends DynamicExpr { arg.expr.decompile(writer); if (arg.variadic) writer.append("..."); } + writer.append(')'); } } diff --git a/muscript/src/main/java/io/gitlab/jfronny/muscript/compiler/Decompilable.java b/muscript/src/main/java/io/gitlab/jfronny/muscript/compiler/Decompilable.java index 3f7f6db..7d48fcb 100644 --- a/muscript/src/main/java/io/gitlab/jfronny/muscript/compiler/Decompilable.java +++ b/muscript/src/main/java/io/gitlab/jfronny/muscript/compiler/Decompilable.java @@ -14,7 +14,7 @@ public abstract class Decompilable { public abstract void decompile(ExprWriter writer) throws IOException; protected void parenthesize(Decompilable val, ExprWriter writer, boolean parenEqualOrder) throws IOException { - boolean wrap = !parenEqualOrder ? val.order.ordinal() > this.order.ordinal() : val.order.ordinal() >= this.order.ordinal(); + boolean wrap = !parenEqualOrder ? val.order.ordinal() < this.order.ordinal() : val.order.ordinal() <= this.order.ordinal(); if (wrap) writer.append('('); val.decompile(writer); if (wrap) writer.append(')'); @@ -33,7 +33,7 @@ public abstract class Decompilable { @Override public String toString() { StringBuilder sb = new StringBuilder(); - try (ExprWriter ew = new ExprWriter(sb)) { + try (ExprWriter ew = new ExprWriter(sb, false)) { decompile(ew); } catch (IOException e) { throw new RuntimeException("Could not decompile", e); diff --git a/muscript/src/main/java/io/gitlab/jfronny/muscript/compiler/ExprWriter.java b/muscript/src/main/java/io/gitlab/jfronny/muscript/compiler/ExprWriter.java index 131eae4..21b1d73 100644 --- a/muscript/src/main/java/io/gitlab/jfronny/muscript/compiler/ExprWriter.java +++ b/muscript/src/main/java/io/gitlab/jfronny/muscript/compiler/ExprWriter.java @@ -2,19 +2,20 @@ package io.gitlab.jfronny.muscript.compiler; import java.io.Closeable; import java.io.IOException; -import java.util.stream.Collectors; public class ExprWriter implements Appendable, Closeable { private final Appendable target; + private final boolean compact; private int indent = 0; - public ExprWriter(Appendable target) { + public ExprWriter(Appendable target, boolean compact) { this.target = target; + this.compact = compact; } @Override public ExprWriter append(CharSequence csq) throws IOException { - target.append(csq.toString().lines().collect(Collectors.joining("\n" + indent()))); + target.append(csq.toString().replace("\r", "").replace("\n", compact ? "" : "\n" + indent())); return this; } @@ -25,8 +26,13 @@ public class ExprWriter implements Appendable, Closeable { @Override public ExprWriter append(char c) throws IOException { - if (c == '\n' || c == '\r') target.append("\n").append(indent()); - else target.append(c); + switch (c) { + case '\r' -> {} + case '\n' -> { + if (!compact) target.append("\n").append(indent()); + } + default -> target.append(c); + } return this; } diff --git a/muscript/src/main/java/io/gitlab/jfronny/muscript/data/dynamic/Dynamic.java b/muscript/src/main/java/io/gitlab/jfronny/muscript/data/dynamic/Dynamic.java index d17749c..c2336bf 100644 --- a/muscript/src/main/java/io/gitlab/jfronny/muscript/data/dynamic/Dynamic.java +++ b/muscript/src/main/java/io/gitlab/jfronny/muscript/data/dynamic/Dynamic.java @@ -27,7 +27,7 @@ public sealed interface Dynamic permits DBool, DNumber, DString, DObject, DLi static String serialize(Dynamic dynamic) { StringBuilder sb = new StringBuilder(); - try (ExprWriter ew = new ExprWriter(sb)) { + try (ExprWriter ew = new ExprWriter(sb, true)) { dynamic.serialize(ew); } catch (IOException e) { throw new RuntimeException("Could not stringify", e); diff --git a/muscript/src/test/java/io/gitlab/jfronny/muscript/test/DecompileTest.java b/muscript/src/test/java/io/gitlab/jfronny/muscript/test/DecompileTest.java new file mode 100644 index 0000000..fec8eb9 --- /dev/null +++ b/muscript/src/test/java/io/gitlab/jfronny/muscript/test/DecompileTest.java @@ -0,0 +1,34 @@ +package io.gitlab.jfronny.muscript.test; + +import io.gitlab.jfronny.muscript.compiler.Parser; +import org.junit.jupiter.api.Test; + +import static org.junit.jupiter.api.Assertions.assertEquals; + +class DecompileTest { + private static final String script = """ + clientVersion = challenge({ -> + mod('better-whitelist').version; + }); + assert(mod('better-whitelist').version == clientVersion, 'You have the wrong mod version'); + assert(challenge({ arg -> + allMatch(arg, { v -> + anyMatch(mods, { m -> + v.name == m.name & v.version == m.version; + }); + }); + }, map(filter(mods, { v -> + v.environment != 'server'; + }), { v -> + { + name = v.name, + version = v.version + }; + }))); + """; + + @Test + void testDecompile() { + assertEquals(script, Parser.parseScript(script).toString()); + } +}